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

如何让UIHostingController内嵌SwiftUI按钮触发UIViewController的delegate

解决方案

核心实现逻辑是给SwiftUI视图增加回调闭包,接收按钮点击事件后通知上层UIViewController处理,具体修改步骤如下:

步骤1:修改FacialTutorial视图

新增回调闭包属性,点击按钮时触发该闭包:

struct FacialTutorial: View {
    // 新增无参数无返回值的闭包,用于对外通知点击事件
    var onButtonTap: () -> Void
    
    var body: some View {
        VStack {
            Button {
                // 按钮点击时执行回调
                onButtonTap()
            } label: {
                Text("Press button")
            }
        }
    }
}

步骤2:修改MyViewController实现

将facialView改为懒加载属性,初始化SwiftUI视图时传入回调闭包,闭包内调用自身的buttonPressed方法即可触发delegate:

class MyViewController: UIViewController {
    public var delegate: MyViewControllerDelegate?
    // 改为懒加载属性,保证初始化时self已经完成初始化,可以正常引用
    lazy var facialView = UIHostingController(rootView: FacialTutorial(onButtonTap: { [weak self] in
        // 避免循环引用,使用weak修饰self
        self?.buttonPressed()
    }))

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        addChild(facialView)
        view.addSubview(facialView.view)
        setupConstraints()
    }

    private func setupConstraints() {
        // 保留原有的约束逻辑即可
    }
}

extension MyViewController {
    @objc private func buttonPressed() {
        delegate?.buttonPressed()
    }
}

适配差异化配置需求

该方案完全适配你提到的多场景配置逻辑:

  • facialView改为懒加载属性后仍然是类的全局成员,你可以在configureForInstructionMode等任意实例方法中正常访问,不会出现nil的问题
  • 懒加载属性只会在第一次被访问时完成初始化,不会影响你不同模式下的差异化配置逻辑
  • 闭包中添加[weak self]修饰符,不会出现循环引用问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 04:15:02