UIControl的addTarget(_:action:for:)与sendAction(_:to:for:)方法有何区别?
UIControl中setTarget与sendAction的区别及适用场景
嘿,刚好我之前做自定义UIControl的时候也纠结过这俩方法,给你掰扯清楚~
先搞懂核心定位
这俩方法其实是UIControl事件响应流程里的两个不同环节:
setTarget(_:action:forControlEvents:)是注册绑定规则的方法,相当于你提前给UIControl“下指令”:「当XX事件(比如点击、值变化)发生时,去通知这个对象(target)执行这个方法(action)」。sendAction(_:to:forEvent:)是主动触发事件通知的方法,它不管有没有提前绑定规则,直接执行「让这个对象(target)执行这个方法(action)」的操作,甚至可以带上事件上下文。
具体区别&适用场景
1. setTarget(_:action:forControlEvents:)
- 作用:建立事件和响应逻辑的绑定关系,是UIControl标准事件响应的基础。
- 适用场景:
- 常规交互场景,比如给自定义按钮绑定点击事件,让视图控制器处理点击逻辑:
// 在视图控制器里 let customButton = MyCustomControl() customButton.addTarget(self, action: #selector(handleButtonTap), for: .touchUpInside) @objc func handleButtonTap() { // 处理点击逻辑 } - 预先确定好响应对象和处理逻辑,希望控件在特定系统事件触发时自动通知响应者。
- 常规交互场景,比如给自定义按钮绑定点击事件,让视图控制器处理点击逻辑:
2. sendAction(_:to:forEvent:)
- 作用:手动触发action的发送,绕过“等待系统事件触发”的环节,直接通知target执行方法。
- 适用场景:
- 自定义控件内部有特殊逻辑,需要在非标准事件触发时通知target。比如自定义一个进度控件,当进度达到100%时,主动通知视图控制器:
// 在自定义UIControl内部 func updateProgress(_ progress: CGFloat) { self.progress = progress if progress >= 1.0 { // 主动发送自定义事件的action sendAction(#selector(MyViewController.handleProgressComplete), to: self.targets.first?.target, for: nil) } } - 手动模拟用户交互,比如在代码里触发按钮点击,而不需要用户真的触摸:
// 模拟按钮点击 customButton.sendAction(for: .touchUpInside) - 动态临时触发某个action,不需要预先绑定规则。比如你可以直接给任意对象发送action,哪怕这个对象没被设置为控件的target:
sendAction(#selector(someMethod), to: someObject, for: nil)
- 自定义控件内部有特殊逻辑,需要在非标准事件触发时通知target。比如自定义一个进度控件,当进度达到100%时,主动通知视图控制器:
关键总结
setTarget是**“定规矩”**,告诉控件未来发生什么事要找谁做什么;sendAction是**“执行规矩”**(或者自己临时加戏),直接触发“找人做事”的动作,不管规矩有没有提前定好。
内容的提问来源于stack exchange,提问作者tim
相关产品推荐
相关产品推荐

