Reputation: 193
I have a swift UIHostingController which renders a SwiftUI. I call a function in view did appear which builds fine but doesn't create the intended output.
class LoginView: UIHostingController<LoginViewComponent> {
required init?(coder: NSCoder) {
super.init(coder: coder, rootView: LoginViewComponent())
}
override func viewDidAppear(_ animated: Bool) {
sessionHandler()
}
func sessionHandler(){
let user = User()
if user.isLoggedIn(){
view.isUserInteractionEnabled = false
print("Authenticating Session")
self.rootView.loginState(state: "success")
}else{
view.isUserInteractionEnabled = true
print("Needs Logging in")
}
}
}
The function ("loginState(state: "success")") works when called within the SwiftUI view class, however when called from the hosting controller it doesn't work.
Any help would be greatly appreciated.
Upvotes: 6
Views: 2830
Reputation: 257663
SwiftUI is reactive state-base machine, actually, and all views are struct values, so you need to change concept, instead of imperatively send messages specify state dependency and reactions on those states...
Thus, keeping your custom-host-controller it could be set up like the following
import SwiftUI
import UIKit
import Combine
// model that keeps login state
class LoginState: ObservableObject {
@Published var state: String = ""
}
struct LoginViewComponent: View {
@EnvironmentObject var loginState: LoginState // state to be observed
...
// somewhere in body you use loginState.state
// and view will be refreshed depending on state changes
}
class LoginView: UIHostingController<AnyView> {
let loginState = LoginState() // here it is created
required init?(coder: NSCoder) {
super.init(coder: coder, rootView: AnyView(LoginViewComponent().environmentObject(self.loginState))) // here the ref injected
}
override func viewDidAppear(_ animated: Bool) {
sessionHandler()
}
func sessionHandler(){
let user = User()
if user.isLoggedIn(){
view.isUserInteractionEnabled = false
print("Authenticating Session")
self.loginState.state = "success" // here state changed
}else{
view.isUserInteractionEnabled = true
print("Needs Logging in")
}
}
}
Upvotes: 1