【问题标题】:Create a Publishable property in a view controller, pass it to a SwiftUI View and listen to changes inside view controller?在视图控制器中创建 Publishable 属性,将其传递给 SwiftUI 视图并监听视图控制器内部的更改?
【发布时间】:2021-02-13 14:37:45
【问题描述】:

这就是我想要达到的目标:

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 视图更改其值时得到通知?

【问题讨论】:

    标签: swiftui combine


    【解决方案1】:

    @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")
              }
        }
    }
    

    【讨论】:

    • 啊,不确定在 SwiftUI 之外使用 ObservableObject。当我回到编码时会尝​​试它。
    • 这行得通。我为此做了一个简单的通用类: class ObservableVariable: ObservableObject { @Published var value: T init(_ val: T) { self.value = val } }
    猜你喜欢
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多