【问题标题】:How do I implement data binding in a View Controller in SwiftUI?如何在 SwiftUI 的视图控制器中实现数据绑定?
【发布时间】:2026-01-10 02:55:02
【问题描述】:

我有一个 UIKit ViewController,它使用 ViewControllerRepresentable 嵌套在 SwiftUI 视图中。 SwiftUI 视图管理我想在 UIKit 视图中显示的一些状态(在此示例中为 Int)。当用户点击 SwiftUI 父视图中的按钮时,状态更改应反映在 UIKit 视图中。我尝试使用 @Binding 属性包装器来保持两者同步,但显然我遗漏了一些东西,因为我的视图控制器的初始化程序引发了编译时错误。

我对 iOS 开发还很陌生,所以我在这里可能走错了方向。任何帮助将不胜感激。

代码如下(简化):

struct ContentView: View {
    @State private var currentNumber: Int

    init(currentNumber: Int) {
        self.currentNumber = currentNumber
    }

    var body: some View {
        FancyLabelViewControllerRepresentable(currentNumber: self.$currentNumber)
        Button("Increment") {
            self.currentNumber += 1
        }
    }
}

struct FancyLabelViewControllerRepresentable: UIViewControllerRepresentable {
    typealias UIViewControllerType = FancyLabelViewController

    @Binding var currentNumber: Int

    init(currentNumber: Binding<Int>) {
        self._currentNumber = currentNumber
    }

    func makeUIViewController(context: Context) -> FancyLabelViewController {
        let fancyLabel = FancyLabelViewController(number: self.currentNumber)
        fancyLabel.currentNumberInLabel = self.currentNumber
        return fancyLabel
    }

    func updateUIViewController(_ uiViewController: FancyLabelViewController, context: Context) {
        uiViewController.currentNumberInLabel = self.currentNumber
    }

}

class FancyLabelViewController: UIViewController {
    var label = UILabel()
    @Binding var currentNumberInLabel: Int

    init(number: Int) {
        // Error: 'self' used in property access 'currentNumberInLabel' before 'super.init' call
        self.currentNumberInLabel = number
        // Error: Property 'self.currentNumberInLabel' not initialized at super.init call
        super.init(nibName: nil, bundle: nil)
    }

    required init(coder: NSCoder) {
        fatalError("Not implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        label.text = "\(currentNumberInLabel)"
        view = label
    }
}

【问题讨论】:

    标签: ios swift swiftui uikit


    【解决方案1】:

    我认为你不需要

    @Binding var currentNumberInLabel: Int
    

    因为UIViewControllerRepresentable 已经负责更新currentNumberInLabel 值,但您还需要更新

    label.text = "\(currentNumberInLabel)"
    

    所以我做了类似的事情

    class FancyLabelViewController: UIViewController {
        var label = UILabel()
        var currentNumberInLabel: Int
    
        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
        }
      
        func updateLabel() {
          label.text = "\(currentNumberInLabel)"
        }
    }
    

    并从UIViewControllerRepresentable调用updateLabel

    func updateUIViewController(_ uiViewController: FancyLabelViewController, context: Context) {
        uiViewController.currentNumberInLabel = self.currentNumber
        uiViewController.updateLabel()
    }
    

    【讨论】:

      最近更新 更多