在视图控制器中创建一个 Publishable 属性,将其传递给 SwiftUI 视图并监听视图控制器内部的变化?

Create a Publishable property in a view controller, pass it to a SwiftUI View and listen to changes inside view controller?

这就是我想要实现的目标:

class MyVC: UIViewController {
    @State var myBoolState: Bool = false

    private var subscribers = Set<AnyCancellable>()

    override func viewDidLoad() {
        super.viewDidLoad()

        myBoolState.sink { value in .... }.store(in:&subscribers)
    }

    func createTheView() {
        let vc = UIHostingController(rootView: MySwiftUIView(myBoolState: $myBoolState))
        self.navigationController!.pushViewController(vc, animated: true)
    }
}

struct MySwiftUIView: View {
    @Binding var myBoolState: Bool

    var body: some View {
          Button(action: {
              myBoolState = true
          }) {
              Text("Push Me")
          }

    }

}

但是上面当然编译不了

所以问题是:我能否以某种方式在视图控制器中声明已发布的 属性,将其传递给 SwiftUI 视图并在 SwiftUI 视图更改其值时得到通知?

@State 包装器仅在 SwiftUI 视图中(按设计)工作,因此您不能在视图控制器中使用它。相反,有 ObsevableObject/ObservedObject 模式用于此目的,因为它基于引用类型。

这是针对您的场景的可能解决方案的演示:

import Combine

class ViewModel: ObservableObject {
    @Published var myBoolState: Bool = false
}

class MyVC: UIViewController {
    let vm = ViewModel()
    
    private var subscribers = Set<AnyCancellable>()

    override func viewDidLoad() {
        super.viewDidLoad()

        vm.$myBoolState.sink { value in
            print(">> here it goes")
        }.store(in:&subscribers)
    }

    func createTheView() {
        let vc = UIHostingController(rootView: MySwiftUIView(vm: self.vm))
        self.navigationController!.pushViewController(vc, animated: true)
    }
}

struct MySwiftUIView: View {
    @ObservedObject var vm: ViewModel

    var body: some View {
          Button(action: {
            vm.myBoolState = true
          }) {
              Text("Push Me")
          }
    }
}