UITableView 中如何复用单元格?

Posted

技术标签:

【中文标题】UITableView 中如何复用单元格?【英文标题】:How cells are reused in UITableView? 【发布时间】:2018-03-29 07:02:00 【问题描述】:

我认为我在 UITableView 中重复使用单元格的方式遗漏了一些东西。

我有带有 TableView 的 ViewController 和带有自己的类和标识符的自定义单元格。在我使用的 cellForRowAt 方法中

let cell: MyCell = myTableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell
    cell.objectForCell = myObject

它可以正常工作,我得到了带有单元格的 TableView。 我也有我传递给我的牢房的对象。在单元格内我有这个代码

var objectForCell : ObjectClass? 
    didSet 
        if let object = objectForCell 
            someLabel.text = object.title
            ....

这也很好用。 但是如果我想给单元格添加一些子视图呢?例如,让它成为每个第三个单元格。当 TableView 出现时,我按预期在每个第三个单元格中看到我的子视图,但是当我开始向不同方向滚动时,为什么我在每个单元格中都有这个子视图?

var objectForCell : ObjectClass? 
    didSet 
        if let object = objectForCell 
            someLabel.text = object.title
            if object.id % 3 == 0 
               self.addSubview(......)
            

【问题讨论】:

只需将视图传递给单元格并在单元格类中将视图添加到awakeFromNib 方法中。 能否请您多描述一下现在发生了什么以及为什么 awakeFromNib 会更好? 您是否打算创建一个新视图并将其作为子视图添加到单元格中?还是它只是一个存在的视图,您想根据单元格的内容显示/隐藏它? 【参考方案1】:

cellForRowAt 将返回一个现有的单元格对象,如果有一个不再被表格视图使用。如果该单元格在呈现时是第三个单元格,则会添加新的subview。因此,要使其按预期工作,您必须在 prepareForReuse 中删除该子视图,当该单元格从视图层次结构中删除并排入可重用单元格队列时,该子视图会被调用。这样当你调用dequeueReusableCell 时,你会得到一个没有新子视图的单元格。

但是,一般情况下,您确实想要在cellForRowAt 中添加/删除子视图(除非没有其他选项)。相反,如果您只想在每三个单元格中显示一个特定视图,请将其添加到 initializer 并在 cellForRowAt 中隐藏/取消隐藏(在您的情况下,在 objectForCell 中)。

所以声明一个属性:

let specialSubview = UIView()

将其添加到init(或者,如果您使用nib,则添加到awakeFromNib)并定位:

self.addSubview(specialSubview)
// autolayout constraints, configuring, etc.

然后在objectForCell:

var objectForCell : ObjectClass? 
    didSet 
        if let object = objectForCell 
            someLabel.text = object.title
            if object.id % 3 == 0 
                specialSubview.isHidden = false
             else 
                specialSubview.isHidden = true
            
            ...

【讨论】:

谢谢,awakeFromNib 有什么方法可以帮上忙吗? @moonvader 正如我在第一段中解释的那样 - 重用意味着您将再次获得之前配置的单元格。如果在配置中添加子视图,则必须在再次使用之前将其删除,否则它们将留在那里。因此,您只需要配置一次子视图——这可以在initializerawakeFromNib 中完成,因为在创建对象时会调用一次。然后在objectForCell 中,您可以简单地显示/隐藏正确的视图。 @moonvader 但这取决于您如何创建单元格 - 我以编程方式完成所有操作,因此在我的情况下,awakeFromNib 根本不使用。如果您使用的是 nib,那么您应该在 awakeFromNib 中创建这些视图。

以上是关于UITableView 中如何复用单元格?的主要内容,如果未能解决你的问题,请参考以下文章

UITableView imageView 复用其他单元格的图片

Swift 4 UITableView 将一个单元格设为 UITextView

在ios的uitableview中自定义单元格编辑样式

点击时表格视图单元格分隔线消失

在 tableviewcell 中使用 UITableview 执行 segue

iOS:如何将 UITableViewCell 附件按钮向左移动