当我点击按钮时,它会触发多次。
CollectionViewCell文件代码
class PhotoCell: UICollectionViewCell {
@IBOutlet weak var deleteButton: UIButton!
}
ViewController - cellforItemAt 方法实现
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as? PhotoCell else { return UICollectionViewCell() }
let action = UIAction { _ in
print("Delete button tapped!!!", indexPath.row)
}
cell.deleteButton.addAction(action, for: .touchUpInside)
return cell
}
如果我配置 UIButton addTarget 那么它工作正常但我不确定为什么它不能与 addAction 一起工作。谢谢!
动作被多次触发,因为
PhotoCell
的一些实例被 UICollectionView
重用。这意味着 deleteButton
返回的 PhotoCell
的 dequeueReusableCell()
可能已经添加了动作,并且最终将拥有针对相同事件的多个动作。
一个可能的解决方案是覆盖
prepareForReuse()
中的PhotoCell
并删除那里的动作。
class PhotoCell: UICollectionViewCell {
@IBOutlet weak var deleteButton: UIButton!
var actions: [(UIAction, UIControl.Event)] = []
func addAction(_ action: UIAction, for event: UIControl.Event) {
self.actions.append((action, event))
self.deleteButton.addAction(action, for: event)
}
override func prepareForReuse() {
super.prepareForReuse()
for tuple in self.actions {
self.deleteButton.removeAction(tuple.0, for: tuple.1)
}
self.actions = []
}
}
使用上述代码时
addAction
需要在cell
上调用,而不是在函数cell.deleteButton
中调用func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as? PhotoCell else { return UICollectionViewCell() }
let action = UIAction { _ in
print("Delete button tapped!!!", indexPath.row)
}
cell.addAction(action, for: .touchUpInside)
return cell
}
一个可能的解决方案是在
prepareForReuse()
中覆盖PhotoCell
,如Johann
所述。
用于执行任何必要的清理 准备视图以供再次使用。preparaForReuse()
我们可以从那里的按钮中删除所有事件!
class PhotoCell: UICollectionViewCell {
@IBOutlet weak var deleteButton: UIButton!
override func prepareForReuse() {
super.prepareForReuse()
self.deleteButton.removeTarget(nil, action: nil, for: .allEvents)
}
}
像往常一样在
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
中添加动作。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as? PhotoCell else { return UICollectionViewCell() }
let action = UIAction { _ in
print("Delete button tapped!!!", indexPath.row)
}
cell.deleteButton.addAction(action, for: .touchUpInside)
return cell
}