从UIHostingController中的SwiftUI调用函数

时间:2019-12-07 16:09:09

标签: ios swift xcode swiftui swift5

我有一个快速的UIHostingController,它呈现一个SwiftUI。我在视图中调用了一个函数,该函数确实可以很好地构建但不能创建预期的输出。

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

}

在SwiftUI视图类中调用该函数(“ loginState(state:” success“)”)时有效,但是在托管控制器中调用时该函数不起作用。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

SwiftUI实际上是基于状态的反应机,所有视图都是结构值,因此您需要更改概念,而不是强制性地发送消息以指定状态依赖性和对这些状态的反应...

因此,可以像下面这样设置您的自定义主机控制器

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

}