如何解决如何使用 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
}
}
解决方法
问题是对“重用”的误解。
假设您的单元格中有一个 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
应仅用于将单元格状态重置为初始状态。
一个单元的重用总是这样进行的:
-
prepareForReuse
被tableView
自身调用 - 在
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 举报,一经查实,本站将立刻删除。