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

从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,点击事件无法被触发。
    修正方法:

    1. 给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)
      }
      
    2. 给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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:30:58