iosswiftuiviewdismiss

Dismissing a view with SwiftUI


I want to show an instruction page the first time a user opens my app. I have gotten this to work, but I cannot understand how to get back to the contentView (without restarting the app).

Just to clarify: I want the "Dismiss this view" button on InstructionView to set the view to be shown to "ContentView" and to dismiss the InstructionView. As it is now the viewRouter.setToContentView() makes the App crash, and I cannot get around it.

Thanks in advance

TestDismissApp

import SwiftUI

@main
struct TestDismissApp: App {
    var body: some Scene {
        WindowGroup {

            MotherView()
        }
    }
}

MotherView

import SwiftUI

struct MotherView : View {
    
    @ObservedObject var viewRouter = ViewRouter()
    
    var body: some View {
        VStack {
            if viewRouter.currentPage == "InstructionView" {
                InstructionView()
            } else if viewRouter.currentPage == "ContentView" {
                ContentView()
            }
        }
    }
}

ViewRouter

import Foundation

class ViewRouter: ObservableObject {
    init() {
        //UserDefaults.standard.set(false, forKey: "didLaunchBefore") remove // if you want to show the instructions again for test reasons
        if !UserDefaults.standard.bool(forKey: "didLaunchBefore") {
            UserDefaults.standard.set(true, forKey: "didLaunchBefore")
            currentPage = "InstructionView"
        } else {
            currentPage = "ContentView"
        }
    }
    
    func setToContentView () {
        currentPage = "ContentView"
    }
    
    @Published var currentPage: String
    
}

ContentView

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("My wonderful content")
            .padding()
    }
}

InstructionView

import SwiftUI

struct InstructionView: View {
    @Environment(\.dismiss) var dismiss
    @EnvironmentObject var viewRouter: ViewRouter
    var body: some View {
        VStack {
            Text("Instruction: This app shows a wonderful sentence")
            
            Button {
                viewRouter.setToContentView()
                dismiss()
            } label: {
                Text("Dismiss this view")
            }

        }
    }
}

Solution

  • try this:

    in MotherView use @StateObject var viewRouter = ViewRouter() and InstructionView().environmentObject(viewRouter)