有人能教我如何使用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"), for: .normal)
cell.editButton.addTarget(self, 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
}}


发布于 2021-02-26 02:54:08
问题是对“重用”的误解。
假设您的计算单元中有一个UIView (我们将其称为someView),您的cellForItemAt函数执行以下操作:
if indexPath.row == 0 {
cell.someView.backgroundColor = .red
}当单元格第一次出列到第0行时,视图的背景将被设置为红色。
现在我们滚动一个方法,这样单元格就是reused...someView的背景仍然是红色的。
所以,一般来说,人们会这样做:
if indexPath.row == 0 {
cell.someView.backgroundColor = .red
} else {
cell.someView.backgroundColor = .white
}您的代码所发生的情况是,您没有设置按钮的属性 --您正在添加一个操作。
因此,每次重用单元格时,您都会添加另一个操作。
在分配新目标之前,您可以每次都使用.removeTarget(...)。
不过,一种更好的方法是在单元类本身中添加.touchUpInside操作,并在cellForItemAt中使用委托/协议模式或闭包(更好)。
顺便说一句,每次重用单元格时,您还会反复向编辑按钮添加宽度和高度约束。由于您每次都添加相同的约束,因此您可能不会遇到问题……但是如果单元格被重用,比如说20次,你的按钮上将有20组宽/高约束。
发布于 2021-02-26 07:25:36
prepareForReuse应该仅用于将单元格状态重置为初始状态。
单元的重用总是这样进行的:
在cellForRowAt中,
prepareForReuse由tableView本身调用示例:我们得到了一个单元格,该单元格将被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函数中调用你的configure方法,图像就被干净地设置好了。
因此,总之,您应该将在计算单元的cellForRowAt函数中配置的所有内容设置回prepareForReuse函数中的初始状态,以确保干净地重用。
https://stackoverflow.com/questions/66373006
复制相似问题