簡體   English   中英

如何在 SwiftUI ViewModel 文件中對 Storyboard 執行 Segue

[英]How To Perform a Segue on a Storyboard in a SwiftUI ViewModel File

我目前正在將一些 SwiftUI view+viewModel 文件注入到 storyboard 中。這樣做的原因是,在將來將應用程序重寫為 SwiftUI 時,我們已經完成了一些工作。 無論如何,我最終創建了一個Hosting Controller ,它將我的 SwitfUI 視圖文件注入到 storyboard 中:

class LoginViewHostingController: UIHostingController<LoginView> {
    required init?(coder: NSCoder) {
        super.init(coder: coder,rootView: LoginView())
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

問題是 SwiftUI View 文件使用 ViewModel 文件(ObservableObject 的實例)來執行它的很多邏輯(主要用於狀態)。

struct LoginView: View  {
        
    @ObservedObject var loginVM = LoginViewModel()
    
    var body: some View {

...然后視圖將像這樣使用loginVM

                        if (!loginVM.showPasswordView) {
                            HStack {
                                Button(action: loginVM.checkEmailForSSOAuthentication) {
                                    Text("Next")
                                        .font(.system(.headline, design: .rounded))
                                        .foregroundColor(Color.white)
                                        .padding(.vertical, 18)
                                        .frame(width: 350)
                                        .background(Color("DigideckPrimary"))
                                        .cornerRadius(6)
                                }
                            }
                            .padding(.top, 10)
                        }

我想要做的,只是為了確認我能做到,是在 storyboard 上執行一個 segue,這個 SwiftUI 視圖被注入到這個 Next 按鈕的操作( loginVM.checkEmailForSSOAuthentication )中,我不確定這是否可能。

我在我的loginVM文件中嘗試這樣做:

    func checkEmailForSSOAuthentication() {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let storyBoardLoginVc = storyboard.instantiateViewController(withIdentifier: "myLoginController")
        // instead of sending to self send to main storyboard if i can!
        storyBoardLoginVc.performSegue(withIdentifier: "test1", sender: self)
        return;

但是當這段代碼執行時收到以下錯誤:

2023-01-18 09:47:00.872611-0600 Digideck[35908:12697138] [Assert] UINavigationBar decoded as unlocked for UINavigationController, or navigationBar delegate set up incorrectly. Inconsistent configuration may cause problems. navigationController=<UINavigationController: 0x130879c00>, navigationBar=<UINavigationBar: 0x127e1ce70; frame = (0 0; 0 50); opaque = NO; autoresize = W; tintColor = UIExtendedSRGBColorSpace 0.0784314 0.392157 0.709804 1; gestureRecognizers = <NSArray: 0x6000010ab090>; layer = <CALayer: 0x600001ec0ea0>> delegate=0x130879c00
2023-01-18 09:47:00.873019-0600 Digideck[35908:12697138] [Presentation] Attempt to present <UINavigationController: 0x130879c00> on <Digideck.LoginViewHostingController: 0x10f00b600> (from <Digideck.LoginViewHostingController: 0x10f00b600>) whose view is not in the window hierarchy.

這讓我相信我實例化了一個不同的 storyboard 而不是引用已經在視圖中的那個。 如果有人知道這是否可行,請告訴我!

我們不在 SwiftUI 中使用視圖 model 對象,因此認為您將能夠在 UIKit 和 SwiftUI 中使用它們不是正確的策略。在 SwiftUI 中,視圖結構是視圖@State它們引用類型語義,即視圖 model object。這行也是一個錯誤:

@ObservedObject var loginVM = LoginViewModel()

@ObservedObject沒有 object 的所有權,所以它是 init 和 deinit 與 View 結構值類型(每個 state 更改)所以基本上你已經創建了一個 memory 泄漏。 你需要像這樣使用它:

@ObservedObject var model: Model

Model已在其他地方初始化,如 singleton,或在應用程序委托中,即它的所有者不是臨時結構值類型。

我認為最好將您的 SwiftUI 視圖設計為使用@Binding var (如果您需要寫訪問權限,否則只需let )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM