使用 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
}
编辑
这是一个更新版本(假设 userExists
和 hasPersonalInfo
被持久化(例如存储在 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())
}
}
}
我正在尝试在 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
}
编辑
这是一个更新版本(假设 userExists
和 hasPersonalInfo
被持久化(例如存储在 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())
}
}
}