So I have been wanting to do this for some time, but I can't figure out how to approach this, so I'm reaching out to see if someone might be able to help me.
So let's say that I have the following code, which when the app loads, loads the "MainView":
struct MapGlider: App {
@ObservedObject var mainViewModel = MainViewModel()
var body: some Scene {
WindowGroup {
MainView()
.environmentObject(mainViewModel)
}
}
}
This loads the map as soon as the app is opened, which is great! All works great there.
Now I will be switching that out to show the OnboardingView() when the app loads such as:
struct MapGlider: App {
@ObservedObject var mainViewModel = MainViewModel()
var body: some Scene {
WindowGroup {
OnboardingView()
}
}
}
Now, I have a OnboardingView
that shows a ZStack with some options, as show in this code below:
struct OnboardingView: View {
@State private var showGetStartedSheet = false
@ObservedObject var mainViewModel = MainViewModel()
var body: some View {
if #available(iOS 16.0, *) {
NavigationStack {
ZStack(alignment: .top) {
VStack {
LazyVGrid(columns: [GridItem(), GridItem(), GridItem(alignment: .topTrailing)], content: {
Spacer()
Image("onboarding-logo")
.border(.red)
NavigationLink(destination: MainView().environmentObject(mainViewModel), label: {
Text("Skip")
})
})
.border(.red)
}
}
.border(.blue)
}
} else {
// Fallback on earlier versions
}
}
}
What I'm trying to achieve:
- When someone clicks on the "Skip" text, to kill the
OnboardingView
and show theMainView()
. - The closest I got is setting a
NavigationLink
, but that had a back button and doesn't work so well, I want to be able to go to theMainView
and not be able to go back toOnboardingView
.
All help will be appreciated!
CodePudding user response:
You could use a container view that conditionally displays the onboarding or main views, depending on the state of a variable (stored at the parent level). That variable can be passed down via a Binding
:
Simplified example that should be easily applicable to your code:
class AppState: ObservableObject {
@Published var showOnboarding = true
}
@main
struct CustomCardViewApp: App {
@StateObject var appState = AppState()
var body: some Scene {
WindowGroup {
MainScreenContainer(showOnboarding: $appState.showOnboarding)
}
}
}
struct MainScreenContainer: View {
@Binding var showOnboarding: Bool
var body: some View {
if showOnboarding {
OnboardingView(showOnboarding: $showOnboarding)
} else {
MainView()
}
}
}
struct OnboardingView: View {
@Binding var showOnboarding: Bool
var body: some View {
Text("Onboarding")
Button("Skip") {
showOnboarding = false
}
}
}
struct MainView: View {
var body: some View {
Text("Main")
}
}