PrepareForReuse在重用后不重置属性和单元格保留行为



在我的collectionView单元格中,我有一个在UIView内部的标签。因此单元格必须根据标签的宽度调整自己的大小,高度是固定的。以下是我如何设置固定高度的代码&动态宽度,只是以防万一,因为我已经看到了一些例子,约束可能导致奇怪的行为:

cvButtons.delegate = self
cvButtons.dataSource = self
cvButtons.contentInset = UIEdgeInsets(top: 0, left: 7, bottom: 0, right: 0)

这里是layoutConfig()代码:

func layoutConfig() -> UICollectionViewCompositionalLayout {
return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in
let itemSize = NSCollectionLayoutSize(widthDimension: .estimated(44), heightDimension: .fractionalHeight(1))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .estimated(44), heightDimension: .absolute(40))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .continuous
return section
}
}

所有这些都很好,单元格被完美地创建,就像每个单元格的宽度是动态的一样。然而,我的要求是,当视图加载时,视图在第一个单元应该有蓝色的背景。所以我写了这段代码:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == cvButtons {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ButtonCategoriesCollectionViewCell", for: indexPath) as! ButtonCategoriesCollectionViewCell

let data = tableSctionHeader[indexPath.row]

cell.lblCategory.text = data

if indexPath.item == 0 {
cell.setBlueColor()
}
else {
cell.setDefault()
}

return cell
}

这是collectionView单元格类

import UIKit
class ButtonCategoriesCollectionViewCell: UICollectionViewCell {

@IBOutlet weak var viewCard: UIView!

@IBOutlet weak var lblCategory: UILabel!

override func awakeFromNib() {
super.awakeFromNib()
// Initialization code

setDefault()
}

override func prepareForReuse() {
super.prepareForReuse()
self.setDefault()
}

func setDefault() {
viewCard.layer.cornerRadius = 15
viewCard.layer.borderWidth = 1
viewCard.layer.borderColor = UIColor.lightGray.cgColor
viewCard.setviewShadowCustomInputs(shadowColor: UIColor.clear.cgColor, shadowOpacity: 0, shadowRadius: 0, shadowWidth: 0, shadowHeight: 0)
}

func setBlueColor() {
viewCard.backgroundColor = UIColor(named: "Color1")
viewCard.layer.borderWidth = 0
viewCard.layer.borderColor = UIColor.clear.cgColor
viewCard.setViewShadow()
lblCategory.textColor = UIColor.white
}

}

这段代码工作得很好,但是我通过使用另一个collectionView重新加载数据。所以,如果我选择一些项目在collectionView,数据刷新和以上的单元格应该重新加载新的数据,这很好,单元格的数量变化和标签,但在某些情况下,而不是索引== 0,其他一些项目也保留蓝色。在某些情况下,所有项目都显示蓝色,而不是在第一个索引的项目。这是我用来更新上面的collectionView的函数:

func updateCollectionView(index: Int) {
if index == 1 {
collectionViewArray = array1
}
else if index == 2 {
collectionViewArray = array2
}
else if index == 3 {
collectionViewArray = array3
}
else if index == 4 {
collectionViewArray = array4
}
else if index == 5 {
collectionViewArray = array5
}
else if index == 6 {
collectionViewArray = array6
}
else if index == 7 {
collectionViewArray = array7
}
else {
collectionViewArray = array8
}
collectionView.reloadData()
}

我只是在didSelectAnItem中调用其他collectionView的这个函数,并从中传递indexPath。

这是正确使用prepareForReuse的方法吗?

prepareForReuse()方法将单元格恢复到初始状态。

如果您在cellForItem(at:)中对单元格的外观进行了任何自定义,那么您通常希望在prepareForReuse()中将这些更改恢复到默认状态。

在您共享的代码中,问题如下:

  1. 对于某个索引路径,调用cell.setBlueColor()
  2. setBlueColor()改变viewCard.backgroundColor
  3. 当相同的单元被用于另一个索引路径时,UIKit调用单元的prepareForReuse()方法,该方法反过来调用setDefault()方法。
  4. 然而,setDefault()方法永远不会将viewCard.backgroundColor恢复到初始值。

如果您在setDefault()中添加一行,将viewCard.backgroundColor设置回您在storyboard/XIB中设置的原始值,它应该可以工作。您可能还需要将lblCategory.textColor重置回其原始值。

但是,这段代码还可以进一步改进:

  1. prepareForReuse()中,不要设置你在cellForItem(at:)中永远不会更改的属性。相反,只需在awakeFromNib()中设置它们一次。例如,你永远不会改变角的半径,所以只需将该线移动到awakeFromNib()
  2. 因为awakeFromNib()prepareForReuse都调用setDefault()方法,当你不做任何单元格的视觉定制时,你不需要从cellForItem(at:)再次调用它。这只是浪费CPU时间,没有任何效果。

相关内容

  • 没有找到相关文章

最新更新