如何在SwiftUI中实现与嵌套UIKit ViewController的数据绑定?
问题解决方案
错误根因
@Binding 是 SwiftUI 专属的属性包装器,只能用于 SwiftUI 的视图结构体,不能在 UIKit 的 UIViewController 子类中使用,这是你出现编译错误的核心原因。
你不需要在 UIKit 侧使用绑定来实现同步,UIViewControllerRepresentable 自带的 updateUIViewController 方法会在 SwiftUI 侧绑定的状态变化时自动触发,你只需要在这个方法内更新 UIKit 视图控制器的属性即可。
修正后的代码
1. 修正 FancyLabelViewController 实现
class FancyLabelViewController: UIViewController { var label = UILabel() // 替换@Binding为普通存储属性,添加didSet观察者自动更新UI var currentNumberInLabel: Int = 0 { didSet { label.text = "\(currentNumberInLabel)" } } init(number: Int) { // 先初始化自身属性,再调用父类初始化,解决编译错误 self.currentNumberInLabel = number super.init(nibName: nil, bundle: nil) } required init(coder: NSCoder) { fatalError("Not implemented") } override func viewDidLoad() { super.viewDidLoad() label.text = "\(currentNumberInLabel)" view = label } }
2. 简化 FancyLabelViewControllerRepresentable 实现
struct FancyLabelViewControllerRepresentable: UIViewControllerRepresentable { typealias UIViewControllerType = FancyLabelViewController @Binding var currentNumber: Int init(currentNumber: Binding<Int>) { self._currentNumber = currentNumber } func makeUIViewController(context: Context) -> FancyLabelViewController { // 初始化时传入初始值即可 FancyLabelViewController(number: currentNumber) } // SwiftUI状态变化时自动调用该方法,同步更新UIKit侧属性 func updateUIViewController(_ uiViewController: FancyLabelViewController, context: Context) { uiViewController.currentNumberInLabel = currentNumber } }
3. ContentView 无需修改即可正常运行
点击按钮时 @State 变化会自动触发 updateUIViewController 执行,UIKit 侧的 label 会随属性变化自动更新文本,实现同步效果。
内容的提问来源于stack exchange,提问作者Niek
相关产品推荐
相关产品推荐

