SwiftUI 清除导航堆栈

时间:2021-06-14 08:36:20

标签: ios swift swiftui swiftui-navigationlink swiftui-navigationview

在我的 iOS 14 SwiftUI 应用程序中,当用户未登录时,我让他在显示主登录屏幕之前通过几个设置屏幕。在最后一个设置屏幕上,我使用 NavigationLink 来显示主登录屏幕。如何清除整个导航堆栈,使登录的主屏幕成为导航堆栈中的根/第一个屏幕?

3 个答案:

答案 0 :(得分:0)

  1. 您可以在根/第一个屏幕上以 .sheet().fullScreenCover() 开头,
  2. 然后与 NaviagtionLink 叠加,
  3. 最后self.presentationMode.wrappedValue.dismiss()

答案 1 :(得分:0)

既然我知道 .sheet().fullscreenCover(),我更喜欢那个答案,但我是 swiftUI 的新手,这是我最初的方法。

您可以使用@State 变量来控制行为。创建两个导航视图,它们包含在基于 bool 的 if 条件中。

@State var showOnBoarding = true
if $showOnBoarding {
  OnboardingNavigationView()
} else {
  CoreNavigationView()
}

一个带有入门链接,另一个包含您的核心导航链接。一个用于您的入职,然后一个用于登录。

您的每个导航链接也将使用 isActive Binding 参数进行初始化。

struct OnboardingNavigationView: View {
    var body: some View {
        NavigationView {
            NavigationLink("Step 1",destination: NextStepView(), isActive: $showOnBoarding)
            //etc..
        }
    }
}

struct CoreNavigationView: View {
    var body: some View {
        NavigationView {
            NavigationLink("Login Screen",destination: AccountView(), isActive: $showOnBoarding)
            //etc..
        }
    }
}

一旦用户登录,您就可以切换该变量。您的每个 NavigationLink 都将使用绑定到 showOnBoarding 的 isActive 属性。因此,一旦登录,他们将无法返回非活动的入职屏幕,而是位于您的“新”导航堆栈中,您的登录屏幕是根屏幕。

请参阅“使用程序激活呈现目标视图”部分 SwiftUI NavigationLink

答案 2 :(得分:0)

出于好奇,我开始考虑一种解决方案来清除我的根视图中的所有内容,并记住设置视图的 .id() 将强制重新加载。

我首先将此作为讨论点而不是作为实际答案发布,因为如果这是一种合法的方法,我对您的意见很感兴趣。

代码被保持在最少以展示总体思路,我还没有考虑任何内存泄漏

import SwiftUI

// MARK: - SessionManager
class SessionManager: ObservableObject {
    var isLoggedIn: Bool = false {
        didSet {
            rootId = UUID()
        }
    }
    
    @Published
    var rootId: UUID = UUID()
}

// MARK: - ContentView
struct ContentView: View {
    @ObservedObject
    private var sessionManager = SessionManager()
    var body: some View {
        NavigationView {
            NavigationLink("ContentViewTwo", destination: ContentViewTwo().environmentObject(sessionManager))
        }.id(sessionManager.rootId)
    }
}

// MARK: - ContentViewTwo
struct ContentViewTwo: View {
    @EnvironmentObject
    var sessionManager: SessionManager
    
    var body: some View {
        NavigationLink("ContentViewTwo", destination: ContentViewThree().environmentObject(sessionManager))
    }
}

// MARK: - ContentViewThree
struct ContentViewThree: View {
    @EnvironmentObject
    var sessionManager: SessionManager
    
    var body: some View {
        NavigationLink("ContentViewThree", destination: ContentViewFour().environmentObject(sessionManager))
    }
}

// MARK: - ContentViewFour
struct ContentViewFour: View {
    @EnvironmentObject
    var sessionManager: SessionManager
    
    var body: some View {
        Button(action: {
            sessionManager.isLoggedIn.toggle()
        }, label: {
            Text("logout")
        })
    }
}

clear stack