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

如何在主ViewController中访问自定义View的按钮点击事件?

实现主ViewController访问自定义View按钮点击事件的几种方式

我来给你捋捋几种靠谱的实现方式,都是iOS开发里常用的套路,你可以根据自己的场景选:

方式一:代理模式(最符合iOS设计规范,适合复杂交互场景)

这种方式能很好地解耦自定义View和主ViewController,适合后续可能扩展更多交互的场景。

步骤1:修改自定义View代码,添加代理协议和代理属性

import UIKit

// 定义代理协议,声明按钮点击的回调方法
protocol TextCustomisationVCDelegate: AnyObject {
    func textCustomisationVCButtonTapped(_ customView: TextCustomisationVC)
}

class TextCustomisationVC: UIView {
    @IBOutlet var contentView: UIView!
    @IBOutlet weak var customButton: UIButton! // 关联XIB里的按钮
    
    // 代理属性,用weak避免循环引用
    weak var delegate: TextCustomisationVCDelegate?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    
    private func commonInit() {
        // 加载XIB到当前View
        Bundle.main.loadNibNamed("TextCustomisationVC", owner: self, options: nil)
        contentView.frame = bounds
        addSubview(contentView)
        
        // 给按钮绑定点击事件(如果XIB里没关联IBAction的话)
        customButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
    }
    
    // 按钮点击的内部处理,调用代理方法通知外部
    @objc private func buttonTapped() {
        delegate?.textCustomisationVCButtonTapped(self)
    }
    
    // 如果你的XIB里已经给按钮关联了IBAction,就替换成下面这段:
    // @IBAction func buttonTapped(_ sender: UIButton) {
    //     delegate?.textCustomisationVCButtonTapped(self)
    // }
}

步骤2:在主ViewController里实现代理

class MainViewController: UIViewController, TextCustomisationVCDelegate {
    @IBOutlet weak var customView: TextCustomisationVC! // 已经关联的自定义View
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 设置自定义View的代理为当前VC
        customView.delegate = self
    }
    
    // 实现代理方法,处理按钮点击逻辑
    func textCustomisationVCButtonTapped(_ customView: TextCustomisationVC) {
        print("自定义View的按钮被点击啦!")
        // 这里可以加你需要的逻辑,比如弹出提示、跳转页面等
        showTapAlert()
    }
    
    private func showTapAlert() {
        let alert = UIAlertController(title: "提示", message: "按钮点击成功", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "确定", style: .default))
        present(alert, animated: true)
    }
}

方式二:闭包回调(简洁直观,适合简单交互场景)

如果你的交互逻辑比较简单,闭包会比代理更简洁,代码量更少。

步骤1:修改自定义View代码,添加闭包属性

import UIKit

class TextCustomisationVC: UIView {
    @IBOutlet var contentView: UIView!
    @IBOutlet weak var customButton: UIButton!
    
    // 定义闭包属性,可选类型,避免未赋值时崩溃
    var onButtonTapped: (() -> Void)?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    
    private func commonInit() {
        Bundle.main.loadNibNamed("TextCustomisationVC", owner: self, options: nil)
        contentView.frame = bounds
        addSubview(contentView)
        
        customButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
    }
    
    @objc private func buttonTapped() {
        // 调用闭包,通知外部处理点击事件
        onButtonTapped?()
    }
}

步骤2:在主ViewController里设置闭包回调

class MainViewController: UIViewController {
    @IBOutlet weak var customView: TextCustomisationVC!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 设置闭包,注意用[weak self]避免循环引用
        customView.onButtonTapped = { [weak self] in
            guard let self = self else { return }
            print("自定义View按钮点击触发闭包!")
            self.showTapAlert()
        }
    }
    
    private func showTapAlert() {
        let alert = UIAlertController(title: "提示", message: "按钮点击成功", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "确定", style: .default))
        present(alert, animated: true)
    }
}

不推荐的方式:直接暴露按钮(破坏封装,尽量避免)

虽然这种方式最简单,但会破坏自定义View的封装性——如果以后你修改自定义View内部的按钮(比如改名、替换成其他控件),主ViewController的代码会直接报错,维护性很差,所以尽量不用:

// 自定义View里把按钮设为public
@IBOutlet public weak var customButton: UIButton!

// 主ViewController里直接给按钮加点击事件
override func viewDidLoad() {
    super.viewDidLoad()
    customView.customButton.addTarget(self, action: #selector(customButtonTapped), for: .touchUpInside)
}

@objc private func customButtonTapped() {
    print("直接绑定按钮的点击事件")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:21:33