使用 NavigationView 从您在 SwiftUI 中离开的地方开始

Start where you left off in SwiftUI with NavigationView

我正在尝试在 SwiftUI 中建立一个多视图工作流,您可以在其中从中断的地方开始,但仍然可以很好地过渡 NavigationView。

作为一个基本示例,我希望它具有 SignupView(您输入用户凭据的位置)> PersonalInfoView(您输入其他个人信息的位置)> etc.

我最初使用简单的 NavigationLink 从一步到下一步。但我也想要这样,如果你完成 SignupView 然后退出应用程序,如果你再次打开它,用户可以直接被带到 PersonalInfoView。就像这样,您可以从上次中断的地方重新开始。

所以我想到了使用条件渲染:

if !userExists { 
  SignupView() 
} else if !hasPersonalInfo {
  PersonalInfoView()
} else {
  Text("Signup complete")
}

但是现在,每当我从 SignupView 转到 PersonalInfoView 时,我都无法像使用 NavigationLink 那样获得漂亮的滑动过渡。如果我添加一个 NavigationLink 去 PersonalInfoView,它会滑入其中(就像典型的导航)然后滑出到视图的另一个版本(条件渲染)。

所以我想我的问题是,在保留整个 NavigationView 范例的同时始终处理条件视图的最佳方法是什么。谢谢

编辑:我可能没有很好地解释我的问题:我仍然想对所有内容使用 NavigationView(以便进行转换、后退按钮等)。我只是希望能够从流程中的不同点开始,但之后的每个视图都将成为导航堆栈的一部分。

您可以明确地将转换应用于视图:

if !userExists { 
  SignupView()
    .transition(.slide)
} else if !hasPersonalInfo {
  PersonalInfoView()
    .transition(.opacity)
} else {
  Text("Signup complete")
    .transition(.slide)
}

此外,对于某些转换,您可能需要在 withAnimation 块内设置 userExists

withAnimation {
    userExists = true
}

编辑

这是一个更新版本(假设 userExistshasPersonalInfo 被持久化(例如存储在 UserDefaults 中):

struct ContentView: View {
    var userExists = true
    var hasPersonalInfo = false

    var body: some View {
        NavigationView {
            VStack {
                if !userExists {
                    SignupView()
                } else if !hasPersonalInfo {
                    PersonalInfoView()
                } else {
                    Text("Signup complete")
                }
            }
        }
    }
}
struct SignupView: View {
    @State private var isLinkActive = false

    var body: some View {
        VStack {
            Text("SignupView")
            Button("Go to PersonalInfoView") {
                self.isLinkActive = true
            }
            .background(NavigationLink(destination: PersonalInfoView(), isActive: $isLinkActive) { EmptyView() }.hidden())
        }
    }
}
struct PersonalInfoView: View {
    @State private var isLinkActive = false

    var body: some View {
        VStack {
            Text("PersonalInfoView")
            Button("Go to MainView") {
                self.isLinkActive = true
            }
            .background(NavigationLink(destination: Text("Signup complete"), isActive: $isLinkActive) { EmptyView() }.hidden())
        }
    }
}