You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UICollectionViewCell中UIButton的UIAction点击多次触发问题

UICollectionViewCell内UIButton的UIAction多次触发问题解决思路

问题原因

UICollectionView的cell采用复用机制,每次调用cellForItemAt时,你都会给按钮添加一个新的UIAction实例。不同于addTarget会自动去重重复的target+selector组合,UIAction每次添加都是独立的对象,不会自动去重。当cell被复用后,之前添加的UIAction并没有被移除,导致按钮上绑定了多个UIAction,点击时所有绑定的动作都会触发。

解决方法

方法1:利用cell复用钩子清理旧Action

在PhotoCell中重写prepareForReuse方法,在cell被复用前移除按钮上对应事件的所有Action:

class PhotoCell: UICollectionViewCell {
    @IBOutlet weak var deleteButton: UIButton!
    
    override func prepareForReuse() {
        super.prepareForReuse()
        // 移除touchUpInside事件下的所有Action
        deleteButton.removeAllActions(for: .touchUpInside)
    }
}

这样每次cell复用前都会清空旧的Action,再添加新的就不会出现累积触发的问题。

方法2:仅给按钮绑定一次Action,通过闭包传递事件

把Action的绑定逻辑放在cell内部(比如awakeFromNib),只绑定一次,然后用闭包将点击事件传递给ViewController。这种方式更符合MVC的职责划分,也从根源避免了重复绑定:

首先修改PhotoCell:

class PhotoCell: UICollectionViewCell {
    @IBOutlet weak var deleteButton: UIButton!
    // 定义闭包用于传递点击事件
    var onDeleteTap: (() -> Void)?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // 只绑定一次Action
        let action = UIAction { [weak self] _ in
            self?.onDeleteTap?()
        }
        deleteButton.addAction(action, for: .touchUpInside)
    }
}

然后修改ViewController的cellForItemAt:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as? PhotoCell else { return UICollectionViewCell() }

    // 给闭包赋值,每次复用更新对应的逻辑
    cell.onDeleteTap = {
        print("Delete button tapped!!!", indexPath.row)
    }

    return cell
}

补充说明

addTarget没有这个问题的核心原因是:当调用addTarget(_:action:for:)时,如果同一个target和selector已经存在于该事件的动作列表中,系统不会重复添加;而UIAction是基于实例的,每次创建的UIAction都是新对象,系统会视为不同的动作,所以会不断累积。

内容的提问来源于stack exchange,提问作者Yogesh Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 13:30:14