UICollectionView 重用单元格背景问题
Posted
技术标签:
【中文标题】UICollectionView 重用单元格背景问题【英文标题】:UICollectionView reuse cell background issue 【发布时间】:2017-06-29 07:53:41 【问题描述】:我正在使用 UICollectionview 呈现 4 个按钮,用户应该选择 1 个按钮。 我创建了 uibutton 的自定义子类:
class CustomButton: UIButton
override var isSelected: Bool
didSet
backgroundColor = isSelected ? Constants.Colors.selectedMenu: Constants.Colors.menuCell
自定义单元格类:
class SymptomCell: UICollectionViewCell
@IBOutlet weak var optionButton1: UIButton!
@IBOutlet weak var optionButton2: UIButton!
@IBOutlet weak var optionButton3: UIButton!
@IBOutlet weak var optionButton4: UIButton!
func configCell(options : [String])
optionButton1.setTitle(options[0], for: .normal)
optionButton2.setTitle(options[1], for: .normal)
optionButton3.setTitle(options[2], for: .normal)
optionButton4.setTitle(options[3], for: .normal)
@IBAction func clickAction(_ sender: UIButton)
sender.isSelected = sender.isSelected ? false : true
我看到,例如,如果我选择按钮并再滚动几个单元格,那么即使我没有按下它,同一索引中的按钮也会获得不同的背景颜色。
在我尝试使用的单元类中:
override func prepareForReuse()
optionButton1.isSelected = false
optionButton2.isSelected = false
// ...
但它每次都会取消选择所有项目。 我该怎么办?
【问题讨论】:
你确定它会取消全选吗? @LeangSocheat 它会在我滑动到下一个单元格时取消选择所有按钮 你的 gif 看起来像页面视图控制器或滚动视图..lolz。 你可以用这个推送你的保留代码吗? @LeangSocheat 请立即查看 【参考方案1】:UICollectionViewCell
内的任何 UIView
在单元重用之间必须是无状态的,因此,您必须保留您的 prepareForReuse
函数。
但是,UICollectionViewCell
本身正在恢复其 isSelected
状态,当它在之前选择的 indexPath
处重复使用时。
因此,方法可以是选择单元格和按钮。 在你的牢房里应该有这样的东西:
protocol MyCellDelegate : NSObjectProtocol
func optionButton1DidToggle(in cell: UICollectionViewCell?)
class MyCell: UICollectionViewCell
var delegate : MyCellDelegate?
@IBAction func clickAction(_ sender: UIButton)
// you can assign delegate to your cell, the same as UICollectionViewDelegate, and forward here click callback to your delegate,
delegate?.optionButton1DidToggle(in: self)
//.....
override var isSelected: Bool
didSet
optionButton1.isSelected = self.isSelected
override func prepareForReuse()
optionButton1.isSelected = false
和MyCellDelegate
实现:
public func optionButton1DidToggle(in cell: UICollectionViewCell?)
if !cell.optionButton1.isSelected
collectionView.selectItem(at: collectionView.indexPath(for: cell) animated:false scrollPosition:.centeredHorizontally)
else
collectionView.deselectItem(at: collectionView.indexPath(for: cell) animated:false)
【讨论】:
如果我只有 1 个“optionButton”怎么办? 你的意思是一个单元格中有多个按钮?然后你需要一个模型在你的UICollectionViewDataSource
后面,每个模型对象将存储每个indexPath
的单元格按钮的状态。您将在UICollectionViewDataSource
的collectionView(_ cellForItemAt: indexPath)
函数中将状态设置为按钮。【参考方案2】:
尝试在您的自定义单元格中使用 prepareForReuse 并设置 backgroundColor = nil
override func prepareForReuse()
backgroundColor = nil
optionButton1.isSelected = false
【讨论】:
以上是关于UICollectionView 重用单元格背景问题的主要内容,如果未能解决你的问题,请参考以下文章