在视图控制器中创建一个 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")
}
}
}
这就是我想要实现的目标:
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")
}
}
}