【问题标题】:Generic UITableViewCell Identifier通用 UITableViewCell 标识符
【发布时间】:2017-09-30 11:02:09
【问题描述】:

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

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

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
//    }
}

有什么想法吗?

谢谢!

【问题讨论】:

  • 为什么不同的表需要不同的标识符?您可以随时检查您在委托函数上出列哪个表,if tableView === self.firstTableView ...
  • 例如,我可以有一个名为 formCell 的单元格类 UITableViewCell 并在另一个视图控制器类 UITableViewCell 中有另一个单元格名为 answerCell。我还可以有一个名为 questionCell 的单元格类 QuestionCell。我认为将我的 formCell 和 answerCell 命名为相同的标识符并不是一件好事

标签: ios swift uitableview generics reuseidentifier


【解决方案1】:
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
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    • 1970-01-01
    • 2020-04-14
    相关资源
    最近更新 更多