I'm trying to have a multi-view workflow in SwiftUI where you can start back where you left off, yet still have nice transitions of NavigationView.
As a basic example, I want it to have SignupView
(where you enter user credentials) > PersonalInfoView
(where you enter other personal info) > etc.
I initially went with a simple NavigationLink from one step to the next. But I also want it so that if you complete the SignupView
and then quit the app, if you open it again, the user can be brought to PersonalInfoView
directly. As in, you can start back where you left off.
So I thought of using conditional rendering:
if !userExists {
SignupView()
} else if !hasPersonalInfo {
PersonalInfoView()
} else {
Text("Signup complete")
}
But now whenever I go from SignupView
to PersonalInfoView
I don't get the nice sliding transition that I would if I were using a NavigationLink. And if I add a NavigationLink to go to PersonalInfoView
, it will slide into it (like a typical navigation) then slide out into the the other version of the view (the conditional rendering one).
So I guess my question is, what's the best way to handle conditional views all the while remaining in the whole NavigationView paradigm. Thanks
EDIT: I might not have explained my issue well enough: I still want to use NavigationView for everything (in order to have the transitions, back button, etc). I just want to be able to start at different points in the process but for every view following that to be part of the navigation stack.
You can explicitly apply transitions to the views:
if !userExists {
SignupView()
.transition(.slide)
} else if !hasPersonalInfo {
PersonalInfoView()
.transition(.opacity)
} else {
Text("Signup complete")
.transition(.slide)
}
Also, for some transitions you may need to set the userExists
inside the withAnimation
block:
withAnimation {
userExists = true
}
EDIT
Here is an updated version (assuming that userExists
and hasPersonalInfo
are persisted (eg. stored in 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())
}
}
}