通用uitableViewCell标识符



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

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

有多个标识符
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
    }
}

最新更新