如何创建不可重用的 UITableViewCell

Posted

技术标签:

【中文标题】如何创建不可重用的 UITableViewCell【英文标题】:How to create a non-reusable UITableViewCell 【发布时间】:2021-02-13 08:05:26 【问题描述】:

编辑:似乎我对“小/固定数量的单元格”的含义并不完全清楚。我的意思是 number 单元格是不变的(总是只有 10 个单元格)。 然而,单元格的内容是非常动态的。我有一个复杂的 UITableViewCell 类来处理这个问题,我很难在给定时间“捕获”每个元素和变量的确切状态,以便“重用”正常工作。

我知道它很不受欢迎……但我想创建不可重用的 UITableViewCells。我决定这样做的原因是因为我只需要少量/固定数量的单元格(准确地说是 10 个),而且它们非常复杂,所以我觉得必须在重用它们之前捕获它们的各种状态,然后重新设置显示每个单元格时的这些状态会非常乏味,特别是因为内存似乎不会成为只有十个 可重用单元格的问题。

但是,我对如何做到这一点感到困惑(实现这一非正统任务的在线资源非常有限)。作为简化测试,我尝试在 cellForRowAt 数据源方法中简单地创建我的 CustomTableViewCell 的实例,但单元格显示为完全空白。在显示单元格之前似乎没有建立任何 IBOutlets(我在单元格的 awakeFromNib() 方法中发布了 print() 语句,但从未调用过)。

有谁知道我遗漏了哪些步骤和/或做错了什么?

供参考,这里是我的表格视图数据源的cellForRowAt方法:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
  
  // Assuming for the sake of the argument that there is only one row (so only one cell needed)...  
  let cell = CustomTableViewCell()
  return cell


我也尝试使用let cell = CustomTableViewCell(style: .default, reuseIdentifier: "customCell") 创建单元格,但这也不起作用。

任何帮助将不胜感激——谢谢!

【问题讨论】:

如果单元格是固定的,请使用带插座的静态单元格。 你能详细说明吗? 其实我的表格没有显示固定数量的单元格(它在1到10之间变化)。但是显示的单元格是预先创建的并且不会更改,因此在这个意义上它们是固定的。很抱歉造成混乱。 如果您只是实例化一个类的实例,则不会连接任何出口,因为连接发生在从情节提要或 nib 文件加载单元的过程中。你没有这样做,所以当然细胞从来都不是“awakeFromNib”。您可以使用不同的重用标识符注册您的单元格,但几乎总是将表格视图与可重用单元格一起使用。 我很难在给定时间“捕获”每个元素和变量的确切状态,以便“重用”正常工作。 为什么?有什么难的?您需要一个特定的数据模型,然后修改模型并重新加载行。在cellForRow 中,将所有 UI 元素设置为已定义的状态。如果单元格中有 UI 元素允许用户交互,请使用回调闭包来更新模型。不重复使用细胞是更糟糕且效率更低的选择。 【参考方案1】:

为了使你的单元格静态,一旦你必须创建 tableViewController 去属性检查器将内容类型从动态变为静态。所以你可以将单元格的数量固定为特定的数量(在下面的第一张和第二张图片中提到)..

enter image description here

enter image description here

【讨论】:

【参考方案2】:

不确定这是否能回答您的问题,但您可以尝试在 CustomTableViewCell() 中调用 override func prepareForReuse()。 例如,如果您想在表格视图中添加一个开关,以避免可重复使用的单元格将列表中的所有开关弄乱,您可以这样做:

override func prepareForReuse() 
    super.prepareForReuse()
    // declare the switch with the default state
    mySwitch.isOn = false
 

【讨论】:

【参考方案3】:

稍微澄清一下...

仅仅因为您使用了可重复使用的单元格,并不意味着您必须对其进行任何“动态”处理。

假设您在 Storyboard 中设计单元格,您可能会有这样的情况:

我设计了 5 个“复杂静态”单元。它们看起来正是我希望它们显示的样子,因此没有自定义单元格类或@IBOutlet 连接。

我所做的只是给每个人一个不同的identifier ...在这种情况下,我使用了“type1”/“type2”/“type3”/“type4”/“type5”。

现在,一个简单的控制器类:

class RowTypesTableViewController: UITableViewController 
    
    var theData: [Int] = []
    
    override func viewDidLoad() 
        super.viewDidLoad()

        theData = [1, 2, 3, 4, 5]

    
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return theData.count
    
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let id: String = "type\(theData[indexPath.row])"
        let cell = tableView.dequeueReusableCell(withIdentifier: id, for: indexPath)
        return cell
    
    

请注意,在cellForRowAt 中我使用数据源值来生成重用标识符:

let id: String = "type\(theData[indexPath.row])"

它加载(出列)正确的“静态”单元格,我得到这个输出:

如果我将数据源数组更改为:

theData = [1, 3, 4]

我明白了:

使用theData = [5, 4]:

并使用theData = [4, 3, 5, 1, 2]:

如您所见,单元格是“静态的”,但我只能按我想要的顺序显示我想要的单元格。

如果您在 xib 文件中设计单元格,请将其添加到 viewDidLoad()

    tableView.register(UINib(nibName: "type1", bundle: nil), forCellReuseIdentifier: "type1")
    tableView.register(UINib(nibName: "type2", bundle: nil), forCellReuseIdentifier: "type2")
    tableView.register(UINib(nibName: "type3", bundle: nil), forCellReuseIdentifier: "type3")
    tableView.register(UINib(nibName: "type4", bundle: nil), forCellReuseIdentifier: "type4")
    tableView.register(UINib(nibName: "type5", bundle: nil), forCellReuseIdentifier: "type5")
    

显然,将“类型”字符串替换为对您的代码有意义的字符串。

【讨论】:

感谢您抽出宝贵时间帮助我。但是,我认为我并不完全清楚我所说的“固定”是什么意思。如果你能看到我对我的问题的编辑,希望它能澄清事情。谢谢! @Eric33187 - 嗯......编辑似乎是一个非常不同的问题。 “捕获”每个元素的确切状态是什么意思?您应该管理您的数据,然后在cellForRowAt 的单元格中设置该数据。如果您的单元格中有用户交互 UI 元素,则您应该在某些内容发生更改时更新您的数据,这样这些更改将在下次使用该单元格时“保留”。 是的,我已经明白我应该按照你的建议去做。如果你有时间,你能看看我的new stack overflow question,它问如何做到这一点?

以上是关于如何创建不可重用的 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章

UITableViewCell - 如何在重用之前重置内容

UITableViewCell的重用机制原理

iOS - 如何在不同的 UITableViewCell 中重用 UIView

如何像 uitableviewcell 一样重用/回收自定义元素?

如何防止 UITableViewCell 重复和重用?

重用自定义UITableViewCell,如何获取每个单元格文本字段的文本进行保存?