Reputation: 6296
This is what I am trying to achieve:
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")
}
}
}
But the above of course does not compile.
So the question is: can I somehow declare a published property inside a view controller, pass it to a SwiftUI View and get notified when the SwiftUI view changes its value?
Upvotes: 3
Views: 1353
Reputation: 257789
The @State
wrapper works (by design) only inside SwiftUI view, so you cannot use it in view controller. Instead there is ObsevableObject/ObservedObject
pattern for such purpose because it is based on reference types.
Here is a demo of possible solution for your scenario:
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")
}
}
}
Upvotes: 4