如何在托管SwiftUI视图的UIViewController中传递@Binding变量
解决UIViewController中SwiftUI @Binding变量传递问题
你遇到的错误核心原因是:在类的属性初始化阶段直接访问$myImage(依赖于self.myImage的Binding包装器)时,类实例self还未完全初始化完成,Swift不允许在这个阶段引用实例成员。
下面提供两种可行的解决方式:
方案1:用延迟加载初始化SwiftUI托管控制器
将UIHostingController声明为lazy var,它的初始化会延迟到第一次被访问时,此时self已经完全初始化,可安全访问$myImage。
import UIKit import SwiftUI class STSChooseItemsViewController: UIViewController { // 定义需要绑定的图片属性 private var myImage: UIImage? // 延迟初始化UIHostingController private lazy var hostingController: UIHostingController<STSChooseItemsView> = { let swiftUIView = STSChooseItemsView(selectedImage: $myImage) return UIHostingController(rootView: swiftUIView) }() override func viewDidLoad() { super.viewDidLoad() // 将SwiftUI视图添加到当前控制器 addChild(hostingController) hostingController.view.frame = view.bounds view.addSubview(hostingController.view) hostingController.didMove(toParent: self) } } // SwiftUI视图定义 struct STSChooseItemsView: View { @Binding var selectedImage: UIImage? var body: some View { // 示例UI:显示选中图片或占位图 Image(uiImage: selectedImage ?? UIImage(systemName: "photo")!) .resizable() .scaledToFit() .padding() } }
方案2:在viewDidLoad中完成SwiftUI视图初始化
不在类属性声明时直接初始化UIHostingController,而是移到viewDidLoad方法中执行——此时self已经完全可用,可正常创建Binding。
import UIKit import SwiftUI class STSChooseItemsViewController: UIViewController { private var myImage: UIImage? private var hostingController: UIHostingController<STSChooseItemsView>? override func viewDidLoad() { super.viewDidLoad() // 在viewDidLoad中初始化,规避self未就绪的问题 let swiftUIView = STSChooseItemsView(selectedImage: $myImage) hostingController = UIHostingController(rootView: swiftUIView) guard let hostingController = hostingController else { return } addChild(hostingController) hostingController.view.frame = view.bounds view.addSubview(hostingController.view) hostingController.didMove(toParent: self) } } struct STSChooseItemsView: View { @Binding var selectedImage: UIImage? var body: some View { Image(uiImage: selectedImage ?? UIImage(systemName: "photo")!) .resizable() .scaledToFit() .padding() } }
两种方案按需选择:方案1适合需要在多个方法中复用hostingController的场景;方案2更轻量化,适合仅初始化一次的简单场景。
内容的提问来源于stack exchange,提问作者Niranjan
相关产品推荐
相关产品推荐

