Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios SwiftUI:更改视图并删除父视图_Ios_Swift_Swiftui_Navigationview - Fatal编程技术网

Ios SwiftUI:更改视图并删除父视图

Ios SwiftUI:更改视图并删除父视图,ios,swift,swiftui,navigationview,Ios,Swift,Swiftui,Navigationview,我有一个带有导航链接的视图。此NavigationLink是一个“注销”按钮,因此当用户单击此按钮时,我不希望他们能够单击导航栏中的返回按钮。是否有方法以编程方式更改视图,并删除“父”视图 以下是带有注销按钮的视图: struct SettingsView: View { @State private var didLogout: Bool = false var body: some View { NavigationView {

我有一个带有
导航链接的视图。此
NavigationLink
是一个“注销”按钮,因此当用户单击此按钮时,我不希望他们能够单击
导航栏中的
返回
按钮。是否有方法以编程方式更改视图,并删除“父”视图

以下是带有注销按钮的视图:

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")
                    }
                }
            }
        }
    }
}
以下是登录视图(当用户注销时,我将推送到的视图):

我删除了一些问题不需要的代码。任何帮助都将不胜感激,因为我在网上找不到关于这个问题的任何信息。我觉得我只是没有正确地表达我的查询,因为我相信很多人在使用SwiftUI之前都遇到过这个问题


正如我所说,如果有一种方法可以“忘记”NavigationView的历史记录,并将其视为堆栈中的顶部视图?

这里有关于“从上到下”或“从下到下”的各种问题和答案,这可能就是您要找的:

但是,另一种常见的模式是根据您是否登录,有条件地显示您的
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")
        }
    }
}

据我所知,这不是一个好的做法,通常,一个好的逻辑故事板设计从一个启动屏幕开始,然后当你进入你推到选项卡栏或边栏屏幕(这是你的主菜单或根菜单)的应用程序时,被登录或注册屏幕取代,它们的每个项目都嵌入到navigationView中,以推到内部视图并从中弹出返回。如果不隐藏并显示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")
        }
    }
}