微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 prepareForReuse

如何解决如何使用 prepareForReuse

有人可以告诉我如何使用prepareForReuse吗?我阅读了文档,但我不明白。我在 tableView 上遇到了一些奇怪的行为。 在 tableviewCell 中,每行有 8 个 collectionViewCell。除了最后一个和倒数第二个单元格之外,每个单元格都有文本,单元格 7 和 8 具有带有用于某些函数调用的图像的文本。
但是每当我滚动并单击第一张图像时,它都会调用这两个函数。它应该只调用它的映射函数(第一个函数),第二个图像也会发生同样的情况。

func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell",for: indexPath) as! CollectionViewCell
    cell.parentVC = self
    cell.index = indexPath.row
    if let val = arrData[indexPath.row] as? String{
        cell.textFieldValue.text = val.trimmingCharacters(in: .whitespacesAndNewlines)
    }
    if let val = arrData[indexPath.row] as? NSNumber{
        cell.textFieldValue.text = (val).stringValue.trimmingCharacters(in: .whitespacesAndNewlines)
    }
    
    cell.textFieldValue.isEditable = false
    cell.layer.borderColor = UIColor.gray.cgColor
    cell.layer.borderWidth = 0.5
    cell.textFieldValue.alignTextVertically()
    
    
    if((indexPath.row == 6) || (indexPath.row == 7)){
        cell.editButton.visibility = .visible
        cell.editButton.heightAnchor.constraint(equalToConstant: 15.0).isActive = true
        cell.editButton.widthAnchor.constraint(equalToConstant: 15.0).isActive = true
        if(indexPath.row == 6){
            cell.editButton.setimage(UIImage(named: "pencil-edit-button.png"),for: .normal)
            cell.editButton.addTarget(self,action: #selector(onCLickEditButton),for: .touchUpInside)
        }else if(indexPath.row == 7){
            cell.textFieldValue.textContainer.maximumNumberOfLines = 2
            cell.textFieldValue.textContainer.lineBreakMode = NSLineBreakMode.byTruncatingTail;
            cell.textFieldValue.alignTextVertically()
            cell.editButton.setimage(UIImage(named: "information.png"),action: #selector(onClickInfoButton),for: .touchUpInside)
        }
    }
    else{
        cell.textFieldValue.textContainer.maximumNumberOfLines = 2
        cell.textFieldValue.textContainer.lineBreakMode = NSLineBreakMode.byCharWrapping;
        cell.editButton.visibility = .gone
        cell.editButton.heightAnchor.constraint(equalToConstant: 0).isActive = true
        cell.editButton.widthAnchor.constraint(equalToConstant: 0).isActive = true
    }
    return cell
}

//CollectionViewCell

class CollectionViewCell: UICollectionViewCell,UITextViewDelegate  {

@IBOutlet weak var textFieldValue: UITextView!
@IBOutlet weak var editButton: UIButton!
var parentVC = UITableViewCell()
var index = Int()


override func awakeFromNib() {
    super.awakeFromNib()
    textFieldValue.delegate = self
    
}

}

enter image description here

enter image description here

解决方法

问题是对“重用”的误解。

假设您的单元格中有一个 UIView(我们将其称为 someView),并且您的 cellForItemAt 函数执行以下操作:

if indexPath.row == 0 {
    cell.someView.backgroundColor = .red
}

第 0 行的单元格第一次出列时,视图的背景将设置为红色。

现在我们滚动一段,以便重用单元格...someView的背景将仍然是红色

所以,一般来说,人们会这样做:

if indexPath.row == 0 {
    cell.someView.backgroundColor = .red
} else {
    cell.someView.backgroundColor = .white
}

您的代码发生了什么,是您没有设置按钮的属性 -- 您正在添加一个操作。

因此,每次重复使用单元格时,您都在添加另一个操作。

在分配新目标之前,您可以每次都使用 .removeTarget(...)

不过,更好的方法是在单元类本身中添加 .touchUpInside 操作,并在 cellForItemAt 中使用委托/协议模式或(更好)闭包。

作为旁注,每次重复使用单元格时,您还会向编辑按钮重复添加宽度和高度约束。由于您每次都添加 相同 约束,因此您可能不会遇到问题……但是如果重复使用单元格,假设 20 次,您的按钮将有 20 组宽度/高度限制。

,

prepareForReuse 应仅用于将单元格状态重置为初始状态。

一个单元的重用总是这样进行的:

  1. prepareForReusetableView 自身调用
  2. cellForRowAt 中调用单元格配置方法

示例: 我们得到了一个单元格,它将被重用于我们 tableView 中的两个单元格。 tableViewCell 包括一个标签和一个 imageView。在这个例子中,我们认为我们根本没有使用 prepareForReuse 函数。

所以我们从配置单元格 1 开始:

label.text = "cell 1"

imageView.image = UIImage(named: "exampleImage")

您的 TableView 尝试重用第 1 个单元格并创建第 2 个单元格:

label.text = "cell 2"

“我们没有为单元格 2 设置 imageView”

现在发生了什么?

单元格 2 将标签中的文本更新为“单元格 2”,但显示来自单元格 1 的图像,因为单元格刚刚被重用,而我们从未将 imageView 的图像置空。如果我们使用函数 prepareForReuse 并设置:

imageView.image = nil

我们正在将 imageView 的图像设置为初始状态。如果我们有一个 3 号单元格再次使用图像,则首先 prepareForReuse 由 tableView 调用,然后您在 cellForRowAt 函数中调用您的配置方法,图像设置干净。>

因此,总而言之,您应该将您在 cellForRowAt 函数中为单元格配置的所有内容设置回 prepareForReuse 函数中的初始状态,以确保干净地重用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。