簡體   English   中英

SwiftUI:更改視圖並刪除父級

[英]SwiftUI: Change view and remove parent

我有一個帶有NavigationLink的視圖。 NavigationLink是一個“注銷”按鈕,因此當用戶單擊此按鈕時,我不希望他們能夠單擊NavigationBar中的"Back"按鈕。 有沒有辦法以編程方式更改視圖並刪除“父”視圖。

這是帶有注銷按鈕的視圖:

struct SettingsView: View {

    @State private var didLogout: Bool = false
    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: Login(), isActive: $didLogout) {
                    Button(action: {
                        //logout code here
                        self.didLogout = true
                    }) {
                        Text("Logout")
                    }
                }
            }
        }
    }
}

這是登錄視圖(我在用戶注銷時推送到的視圖):

struct Login: View {
    
    //Login states
    @State var isActive = false
    @State var attemptingLogin = false
    @State var didLoginFail = false
    
    var body: some View {
        
        NavigationView {
            VStack {
                if (attemptingLogin == true) {
                    ProgressView()
                        .progressViewStyle(CircularProgressViewStyle())
                }
                
                NavigationLink(destination: blah(), isActive: $isActive) {
                    Button(action: {
                        attemptingLogin = true
                        blah.Login() { didLogin in
                            if didLogin == true {
                                self.isActive = true
                            } else {
                                self.isActive = false
                                self.didLoginFail = true
                                self.attemptingLogin = false
                            }
                        }
                    }) {
                        Text("Login")
                    }
                }        
            }.padding()
        }
    }
}

我刪除了一些問題不需要的代碼。 任何幫助將不勝感激,因為我在網上找不到任何關於這個問題的東西。 我覺得我的查詢措辭不正確,因為我確信很多人在使用 SwiftUI 之前遇到過這個問題。

就像我說的,如果有辦法“忘記” NavigationView 的歷史,並將其視為堆棧中的頂視圖?

SO上有關於“pop to top”或“pop to root”的各種問題和答案,這可能是您正在尋找的:

但是,另一種常見的模式是根據您是否登錄有條件地顯示您的NavigationView 這可能看起來像這樣:

class StateManager : ObservableObject {
    @Published private(set) var isLoggedIn = false
    
    func changeLogin(state: Bool) {
        withAnimation {
            isLoggedIn = state
        }
    }
}

struct ContentView: View {
    @StateObject var stateManager = StateManager()
    
    var body: some View {
        if stateManager.isLoggedIn {
            LoggedInView(stateManager: stateManager)
                .transition(.slide)
        } else {
            LoginView(stateManager: stateManager)
                .transition(.slide)
        }
    }
}

struct LoginView : View {
    @ObservedObject var stateManager : StateManager
    
    var body: some View {
        Button("Log in") {
            stateManager.changeLogin(state: true)
        }
    }
}

struct LoggedInView : View {
    @ObservedObject var stateManager : StateManager
    
    var body: some View {
        NavigationView {
            Button("Log out") {
                stateManager.changeLogin(state: false)
            }.navigationBarTitle("Logged in")
        }
    }
}

到目前為止我所看到的,這不是一個好習慣,通常是一個好的邏輯 storyboard 設計從啟動屏幕開始,然后在您進入應用程序時被登錄或注冊屏幕取代,您推送到標簽欄或側邊欄屏幕您的主菜單或根菜單及其每個項目都嵌入在導航視圖中,以推送到內部視圖並從它們彈出到 go 回來。 如果你不隱藏和顯示navigationView會更好。

暫無
暫無

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

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