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

Swift自定义UIButton报unrecognized selector错误如何优化?

崩溃原因

你当前的代码在调用addTarget时,将外部传入的target作为响应选择器的对象,但#selector(tapAction(_:))是定义在BaseButton内部的私有方法,外部target(报错里的UIView实例)不存在该方法,因此触发了无法识别选择器的崩溃。你不需要将target作为参数传入,响应点击的主体本身就是按钮实例。

现有代码修复方案

修改BaseButton的tapInside方法,移除不必要的target参数,将addTarget的响应对象固定为self:

class BaseButton: UIButton {
    
    private var action: ((UIButton)->())?

    // 移除target参数
    public func tapInside(action: ((UIButton)->())?) {
        self.action = action
        // 响应点击的是按钮自身,所以target填self
        self.addTarget(self, action: #selector(tapAction(_:)), for: .touchUpInside)
    }

    @objc private func tapAction(_ sender: UIButton) {
        action?(self)
    }
}

调用示例:

let testBtn = BaseButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
testBtn.tapInside { [weak self] sender in
    // 处理点击逻辑
}
无需自定义子类的通用实现

如果不想继承BaseButton,可以通过Swift关联对象给系统UIButton扩展点击闭包能力,全项目的UIButton都可以直接使用:

import UIKit

// 关联对象的唯一key
private var UIButtonTapActionKey: UInt8 = 0

extension UIButton {
    // 用关联对象存储点击闭包
    private var tapAction: ((UIButton) -> Void)? {
        get {
            objc_getAssociatedObject(self, &UIButtonTapActionKey) as? (UIButton) -> Void
        }
        set {
            objc_setAssociatedObject(self, &UIButtonTapActionKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
    }
    
    // 对外暴露的添加点击事件方法
    func addTapAction(_ action: @escaping (UIButton) -> Void) {
        self.tapAction = action
        addTarget(self, action: #selector(internalHandleTap(_:)), for: .touchUpInside)
    }
    
    // 内部私有响应方法
    @objc private func internalHandleTap(_ sender: UIButton) {
        tapAction?(sender)
    }
}

调用示例:

let systemBtn = UIButton(type: .system)
systemBtn.addTapAction { [weak self] sender in
    // 处理点击逻辑
}
注意事项
  • 闭包内引用外部对象时必须添加[weak self]标记,避免循环引用导致内存泄漏
  • 重复调用添加点击的方法会覆盖之前设置的闭包,如果需要添加多个点击回调请使用系统原生的addTarget方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 18:09:05