【问题标题】:Simplifying cellForRowAt in TableView简化 TableView 中的 cellForRowAt
【发布时间】:2020-05-19 16:21:51
【问题描述】:

我正在编写一个个人 iOS 应用程序来跟踪一些事情。我的应用程序运行良好,但我将注意力转向整理代码和清理工作。在我的 tableview 中,其中一个单元格是 uicollectionview,根据我选择的 collectionviewcell,自定义 tableviewcell 会加载到同一个表中。此时,我的 collectionview 中有大约十几个项目,我可以从中选择,然后从大约十几个不同的 tableviewcells 中选择一个来加载。每个单元收集不同的信息位。

一切都按我的预期工作,但我不喜欢在整个 tableviewcontroller 中,我有许多基于我必须处理的 tableviewcells 的重复部分

override func viewDidLoad() {
    super.viewDidLoad()
    // register the various tablecells
    tableView.register(UINib(nibName: "eventO2TableViewCell", bundle: nil), forCellReuseIdentifier: "eventO2TableViewCell")
...
    tableView.register(UINib(nibName: "eventTmpTableViewCell", bundle: nil), forCellReuseIdentifier: "eventTmpTableViewCell")
    tableView.register(UINib(nibName: "eventDXTableViewCell", bundle: nil), forCellReuseIdentifier: "eventDXTableViewCell")

同样的 cellForRowAt 非常大(即一个 switch 语句,十几个 case ,每个都有一个对应的

switch selectedIndexPath.row { // the index of the uicollectionviewcell
case 1:
    let cell = tableView.dequeueReusableCell(withIdentifier: "eventTmpTableViewCell", for: indexPath) as! eventTmpTableViewCell
    return cell
...
case 11:
    let cell = tableView.dequeueReusableCell(withIdentifier: "eventO2TableViewCell", for: indexPath) as! eventO2TableViewCell
    return cell
default:
    let cell = tableView.dequeueReusableCell(withIdentifier: "eventDXTableViewCell", for: indexPath) as! eventDXTableViewCell
    return cell
}

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

另一个带有十几个案例评估的 switch 语句来确定使用了哪个单元格并提取我需要保存的信息。

正在考虑在类似问题Is it possible to store custom UITableViewCell into Array? 中提出的想法,但好奇是否有其他建议?仍然认为自己是这个领域的初学者。谢谢

【问题讨论】:

  • 也许这会对你有所帮助:medium.com/chili-labs/…
  • 非常感谢您,我将查看 Medium 文章,看看如何最好地适应我的设置...

标签: ios swift uitableview


【解决方案1】:

我为UITableView 中的registerdeque 以及UITableViewCell 中的identifier 创建了扩展,这里是一些示例代码:

UITableViewExtension.swift

public extension UITableView {

    func register<CellClass: UITableViewCell>(_ cellClass: CellClass.Type) {
        register(cellClass, forCellReuseIdentifier: cellClass.identifier)
    }

    func dequeue<CellClass: UITableViewCell>(
        _ cellClass: CellClass.Type,
        for indexPath: IndexPath,
        setup: ((CellClass) -> Void)? = nil) -> UITableViewCell {
        let cell = dequeueReusableCell(withIdentifier: cellClass.identifier, for: indexPath)
        if let cell = cell as? CellClass {
            setup?(cell)
        }
        return cell
    }
}

UITableViewCell.swift

extension UITableViewCell {
    static var identifier: String {
        return String(describing: self)
    }
}

然后在 ViewController.swift 中

class Cell1: UITableViewCell {
    // ...
}
class Cell2: UITableViewCell {
    // ...
}

class ViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let cells = [Cell1.self, Cell2.self]
        tableView.register(cells)
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return tableView.dequeue(Cell1.self, for: indexPath) { cell in
            // customise cell
        }
    }
}

注意:正如您所要求的,我将 UITableViewCells 存储到单元格数组中并完成我的工作。尽管我们的实现有细微的变化,但我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您可以创建一个协议DequeueInitializable 并像这样编写它的扩展

    import Foundation
    import UIKit
    
    protocol DequeueInitializable {
        static var reuseableIdentifier: String { get }
    }
    
    extension DequeueInitializable where Self: UITableViewCell {
    
        static var reuseableIdentifier: String {
            return String(describing: Self.self)
        }
    
        static func dequeue(tableView: UITableView) -> Self {
            guard let cell = tableView.dequeueReusableCell(withIdentifier: self.reuseableIdentifier) else {
                return UITableViewCell() as! Self
            }
            return cell as! Self
        }
        static func register(tableView: UITableView)  {
            let cell = UINib(nibName: self.reuseableIdentifier, bundle: nil)
            tableView.register(cell, forCellReuseIdentifier: self.reuseableIdentifier)
        }
    }
    

    然后在你的单元类中你确认该协议

    class Cell1: UITableViewCell, DequeueInitializable { }
    class Cell2: UITableViewCell, DequeueInitializable { }
    

    现在您可以轻松注册和出列单元格

    return Cell1.dequeue(tableView: tableView)
    

    注册

    Cell1.register(tableView: tableView)
    

    【讨论】:

      猜你喜欢
      • 2018-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多