ios - 通用 UITableViewCell 标识符

标签 ios swift uitableview generics reuseidentifier

我尝试使用类型和枚举而不是字符串作为 cellIdentifier

我不想使用单元格类名作为标识符,因为我可以为一种类型的单元格(例如不同 TableView 中的基本单元格)使用多个标识符

enum TableViewCellIdentifier: String {
    case formCell, questionCell

    // Here I can have the type, and I want to use it to ensure the cell dequeued by the identifier is the right type
    var typeCell: UITableViewCell.Type {
        switch self {
        case .formCell:
            return UITableViewCell.self
        case .questionCell:
            return QuestionCell.self
        }
    }

    // I could use an extension of UITableView to build an other version of dequeueCell,
    // but I'll choose after it the type constraint will let me choose.

    // Here I want to constraint the return type with the value of myValue.typeCell
    func dequeueCell(with tableView: UITableView, for indexPath: IndexPath) -> UITableViewCell {
        return tableView.dequeueReusableCell(withIdentifier: self.rawValue, for: indexPath)
    }
//    func dequeueCell<T: self.typeCell>(with tableView: UITableView, for indexPath: IndexPath) -> T {
//        return tableView.dequeueReusableCell(withIdentifier: self.rawValue, for: indexPath) as! T
//    }
}

有什么想法吗?

谢谢!

最佳答案

import Foundation
import UIKit

protocol Reusable: class{
    static var reuseIdentifier: String { get }
}

extension Reusable {
    static var reuseIdentifier: String {
        return String(describing: self)

    }
}

extension UITableViewCell: Reusable{}
extension UITableViewHeaderFooterView: Reusable{}

protocol NibLoadableView {
    static var nibName: String { get }
}

extension NibLoadableView  {
    static var nibName: String {
        return String(describing: self)
    }
}

extension UITableViewCell: NibLoadableView {}

extension UITableView {

    func register<T: UITableViewCell>(_: T.Type)  {
        register(T.self, forCellReuseIdentifier: T.reuseIdentifier)
    }

    func registerNib<T: UITableViewCell>(_: T.Type)  {
        let bundle = Bundle(for: T.self)
        let nib = UINib(nibName: T.reuseIdentifier, bundle: bundle)
        print(T.nibName, T.reuseIdentifier)
        register(nib, forCellReuseIdentifier: T.reuseIdentifier)
    }

    func registerHeaderNib<T: UITableViewHeaderFooterView>(_: T.Type)  {
        let bundle = Bundle(for: T.self)
        let nib = UINib(nibName: T.reuseIdentifier, bundle: bundle)
        print(T.reuseIdentifier, T.reuseIdentifier)
        register(nib, forHeaderFooterViewReuseIdentifier: T.reuseIdentifier)
    }

    func dequeueReusableCell<T: UITableViewCell>(for indexPath: IndexPath) -> T  {
        print(T.reuseIdentifier)
        guard let cell = dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as? T else {
            fatalError("Could not dequeue cell with identifier: \(T.reuseIdentifier)")
        }
        return cell
    }

    func dequeueReusableHeaderFooterView<T: UITableViewHeaderFooterView>(for section: Int) -> T  {
        print(T.reuseIdentifier)
        guard let cell = dequeueReusableHeaderFooterView(withIdentifier: "DemoHeaderView") as? T else {
            fatalError("Could not dequeue cell with identifier: \(T.reuseIdentifier)")
        }
        return cell
    }

}

这就是 ViewContoller 将如何使用它。

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(TestCell.self)

       let headerNib = UINib.init(nibName: "DemoHeaderView", bundle: Bundle.main)
       tableView.register(headerNib, forHeaderFooterViewReuseIdentifier: "DemoHeaderView")
        tableView.registerHeaderNib(DemoHeaderView.self)

    }



    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

    }  
}

extension ViewController: UITableViewDataSource, UITableViewDelegate {
    // MARK: - UITableView delegate
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 4
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: TestCell = tableView.dequeueReusableCell(for: indexPath)
        cell.textLabel?.text  = "\(indexPath.row)"
        return cell
    }

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        let headerView = tableView.dequeueReusableHeaderFooterView(for: section)


        return headerView
    }
}

关于ios - 通用 UITableViewCell 标识符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46502086/

相关文章:

ios - 将图像和文本字段上传到 iOS objective-c 中的服务器多部分数据

ios - 启用内容插入的 UIScrollView 分页工作异常

arrays - UITableView SearchBar过滤查询

ios - 如何在 IOS 中的联系人更改事件中得到通知?

swift - 为什么 "Show"Segue 更新 UITableViewCells 但不更新 reloadData()?

ios - 如何快速取消特定的 UILocalNotification?

ios - 即使未实现,uilongpressgesturerecognizer 也会崩溃

ios - 如何创建带有移动箭头的滑动开始按钮

ios - 为一个 Controller [ Storyboard] 创建纵向和横向 View 的最佳方法是什么?

ios - Xcode 6.4 后退按钮消失