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

Posted

技术标签:

【中文标题】在视图控制器中创建 Publishable 属性,将其传递给 SwiftUI 视图并监听视图控制器内部的更改?【英文标题】:Create a Publishable property in a view controller, pass it to a SwiftUI View and listen to changes inside view controller? 【发布时间】: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 视图更改其值时得到通知?

【问题讨论】:

【参考方案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

以上是关于在视图控制器中创建 Publishable 属性,将其传递给 SwiftUI 视图并监听视图控制器内部的更改?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不同的视图控制器中创建插座?

如何在 iPad 的视图控制器中创建多个表格视图?

如何在 Swift iOS 中创建一个通用的弹出视图控制器

在所有视图控制器中创建警报功能 - swift

在 MVC 中创建具有上下文的控制器时如何省略视图的生成?

在 iOS5 视图控制器中创建链接/按钮动态列表的最佳方法