SwiftUI视图未更新以反映UIViewController中的数据更改

时间:2020-04-22 16:14:37

标签: ios uikit swiftui

我一直在尝试使用SwiftUI和UIKit,试图了解如何在两个框架之间共享数据,并且为正在处理的更大项目创建了一个简单示例。该示例是单个SwiftUI视图,其中包含包装了自定义视图控制器的UIViewControllerRepresentatable。我正在尝试让SwiftUI视图显示视图控制器属性之一的值,但更改该值后无法正确刷新。

struct ContentView: View {
    @State var viewController = MyViewControllerRepresentable()
    var body: some View {
        VStack {
            viewController
            Text("super special property: \(viewController.viewController.data)")
        }
    }
}
class MyViewController: UIViewController, ObservableObject {
    @Published var data = 3

    override func viewDidLoad() {
        let button = UIButton(type: .system)
        button.setTitle("Increase by 1", for: .normal)
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        view = button
    }

    @objc func buttonPressed() {
        data += 1
    }
}


struct MyViewControllerRepresentable: UIViewControllerRepresentable {
    @ObservedObject var viewController = MyViewController()

    func makeUIViewController(context: Context) -> UIViewController {
        return self.viewController
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}

当我运行应用程序并按下按钮时,我可以看到data的实际值正​​在更改,并且MyViewController中的发布者正在触发,但是屏幕上显示的值没有刷新反映这一点。

请注意,我是iOS开发的新手,这可能是一个非常规的数据模型。但是,我不明白为什么它不能正常工作。建议使用更好的共享数据的方法将不胜感激,但我主要想知道是否有可能将其与当前数据结构一起使用。

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以创建一个@Binding。这意味着当更新data的值时,将重新创建视图以反映更改。

这是怎么做:

struct ContentView: View {

    @State private var data = 3

    var body: some View {
        VStack {
            MyViewControllerRepresentable(data: $data)
            Text("super special property: \(data)")
        }
    }
}


class MyViewController: UIViewController {

    @Binding private var data: Int

    init(data: Binding<Int>) {
        self._data = data
        super.init(nibName: nil, bundle: nil)
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    override func viewDidLoad() {
        let button = UIButton(type: .system)
        button.setTitle("Increase by 1", for: .normal)
        button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        view = button
    }

    @objc func buttonPressed() {
        data += 1
    }
}


struct MyViewControllerRepresentable: UIViewControllerRepresentable {

    @Binding var data: Int
    private let viewController: MyViewController

    init(data: Binding<Int>) {
        self._data = data
        viewController = MyViewController(data: data)
    }


    func makeUIViewController(context: Context) -> UIViewController {
        viewController
    }
    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}