我一直在尝试使用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开发的新手,这可能是一个非常规的数据模型。但是,我不明白为什么它不能正常工作。建议使用更好的共享数据的方法将不胜感激,但我主要想知道是否有可能将其与当前数据结构一起使用。
谢谢。
答案 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) {}
}