从ViewController为View中按钮添加点击事件无响应问题排查
自定义View中按钮添加Target无响应的排查与解决
问题描述
尝试从ViewController为自定义View中创建的按钮添加target时,按钮点击无任何响应;但直接在ViewController中创建该按钮,点击功能可正常工作。
相关代码
class ViewController: UIViewController { var mainView = MainView() var counter:Int = 0 @objc func buttonAction(sender:UIButton!) { counter += 1 print("Button was predded:\(counter)") mainView.lable1.text = "Button was predded:\(counter)" } override func viewDidLoad() { super.viewDidLoad() view.addSubview(mainView) mainView.buttno1.addTarget(self, action: #selector(buttonAction), for: UIControl.Event.touchUpInside) } } class MainView : UIView { var background: UIView = { return background }() lazy var buttno1: UIButton = { var btn = UIButton() .... return btn }() func createButton1(){ print("Main view btn created") background.addSubview(buttno1) } override init(frame: CGRect) { super.init(frame: frame) self.addSubview(background) createButton1() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
可能的原因及解决方法
background属性初始化循环引用,直接导致崩溃
你的background初始化代码存在严重错误:闭包里直接返回未初始化的background属性,会触发循环引用初始化崩溃,程序运行到这一步就会卡死,后续的按钮创建、Target绑定逻辑根本不会执行。
修正方法:正确初始化background视图:var background: UIView = { let view = UIView() view.backgroundColor = .white // 可根据需求设置属性 view.translatesAutoresizingMaskIntoConstraints = false return view }()视图未设置有效布局,按钮不在可视区域
如果mainView、background或buttno1(注意拼写错误,建议改为button1)没有设置正确的frame或Auto Layout约束,可能导致按钮处于屏幕外,或者父视图尺寸为CGRect.zero,点击事件无法被触发。
修正方法:- 给
mainView添加铺满父视图的约束:override func viewDidLoad() { super.viewDidLoad() view.addSubview(mainView) mainView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ mainView.topAnchor.constraint(equalTo: view.topAnchor), mainView.leadingAnchor.constraint(equalTo: view.leadingAnchor), mainView.trailingAnchor.constraint(equalTo: view.trailingAnchor), mainView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) mainView.buttno1.addTarget(self, action: #selector(buttonAction), for: .touchUpInside) } - 给
background和按钮也添加合适的约束,确保按钮处于屏幕可视区域内。
- 给
按钮交互被禁用
检查按钮的isUserInteractionEnabled属性是否被设置为false,如果是则无法响应点击。默认该属性为true,但如果初始化时被修改过,需要重新开启:lazy var buttno1: UIButton = { var btn = UIButton() btn.isUserInteractionEnabled = true // 其他属性设置 return btn }()变量名拼写错误(潜在隐患)
你的按钮变量名是buttno1(正确应为button1),虽然当前代码内拼写一致,但后续修改时容易出现不匹配,建议修正变量名避免潜在问题。
修正后的完整代码示例
class ViewController: UIViewController { var mainView = MainView() var counter: Int = 0 @objc func buttonAction(sender: UIButton!) { counter += 1 print("Button was pressed:\(counter)") // 若存在label1,需确保其正确初始化并添加约束 // mainView.label1.text = "Button was pressed:\(counter)" } override func viewDidLoad() { super.viewDidLoad() view.addSubview(mainView) // 设置mainView约束 mainView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ mainView.topAnchor.constraint(equalTo: view.topAnchor), mainView.leadingAnchor.constraint(equalTo: view.leadingAnchor), mainView.trailingAnchor.constraint(equalTo: view.trailingAnchor), mainView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) mainView.button1.addTarget(self, action: #selector(buttonAction), for: .touchUpInside) } } class MainView : UIView { var background: UIView = { let view = UIView() view.backgroundColor = .white view.translatesAutoresizingMaskIntoConstraints = false return view }() lazy var button1: UIButton = { let btn = UIButton(type: .system) btn.setTitle("Click Me", for: .normal) btn.translatesAutoresizingMaskIntoConstraints = false return btn }() func createButton1(){ print("Main view btn created") background.addSubview(button1) // 设置按钮约束 NSLayoutConstraint.activate([ button1.centerXAnchor.constraint(equalTo: background.centerXAnchor), button1.centerYAnchor.constraint(equalTo: background.centerYAnchor), button1.widthAnchor.constraint(equalToConstant: 120), button1.heightAnchor.constraint(equalToConstant: 40) ]) } override init(frame: CGRect) { super.init(frame: frame) self.addSubview(background) // 设置background约束 NSLayoutConstraint.activate([ background.topAnchor.constraint(equalTo: self.topAnchor), background.leadingAnchor.constraint(equalTo: self.leadingAnchor), background.trailingAnchor.constraint(equalTo: self.trailingAnchor), background.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) createButton1() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
内容的提问来源于stack exchange,提问作者ALEX
相关产品推荐
相关产品推荐

