Swift中UIButton的addTarget方法默认参数不生效问题求助
以下是测试代码:
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. let btn = UIButton.init(frame: CGRect(x: 100, y: 100, width: 100, height: 100)); btn.backgroundColor = UIColor.blue btn.addTarget(self, action: #selector(testAction(_:animated:)), for: .touchDown) view.addSubview(btn) } @objc func testAction(_ sender: UIButton,animated: Bool = true){ if sender.backgroundColor == UIColor.red { sender.backgroundColor = UIColor.blue }else{ sender.backgroundColor = UIColor.red } print("animated == \(animated)") } }
点击按钮后,打印出的animated值始终为false,这不是系统bug,而是Objective-C运行时与Swift默认参数机制不兼容导致的:
- UIKit的Target-Action机制基于Objective-C运行时实现,但Objective-C本身没有默认参数的概念。
- 对于
touchDown这类按钮事件,OC运行时只会传递一个参数(触发事件的控件本身,也就是sender),无法识别Swift方法里的默认参数并自动填充值。 - 当Swift方法的参数未被OC运行时传递值时,会被初始化为对应类型的“零值”——Bool类型的零值就是
false,所以你看到的结果是false。
解决方法
可以通过拆分方法的方式规避这个问题:
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let btn = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 100)) btn.backgroundColor = .blue // 绑定不带默认参数的OC兼容方法 btn.addTarget(self, action: #selector(btnTapAction(_:)), for: .touchDown) view.addSubview(btn) } // 暴露给OC运行时的方法,无默认参数 @objc private func btnTapAction(_ sender: UIButton) { // 内部调用带默认参数的方法,手动传入默认值 testAction(sender, animated: true) } // 保留原业务逻辑方法,可继续用于Swift内部调用 func testAction(_ sender: UIButton, animated: Bool = true) { sender.backgroundColor = sender.backgroundColor == .red ? .blue : .red print("animated == \(animated)") } }
这样既保留了原方法的默认参数能力,又能让Target-Action机制正常工作,点击按钮后animated会正确打印为true。
内容的提问来源于stack exchange,提问作者god pp
相关产品推荐
相关产品推荐

