Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI transition from modal sheet to regular view with Navigation Link

I'm working with SwiftUI and I have a starting page. When a user presses a button on this page, a modal sheet pops up.

In side the modal sheet, I have some code like this:

  NavigationLink(destination: NextView(), tag: 2, selection: $tag) {
            EmptyView()
    }

and my modal sheet view is wrapped inside of a Navigation View.

When the value of tag becomes 2, the view does indeed go to NextView(), but it's also presented as a modal sheet that the user can swipe down from, and I don't want this.

I'd like to transition from a modal sheet to a regular view.

Is this possible? I've tried hiding the navigation bar, etc. but it doesn't seem to make a difference.

Any help with this matter would be appreciated.

like image 318
Evan Avatar asked Oct 27 '25 07:10

Evan


1 Answers

You can do this by creating an environmentObject and bind the navigationLink destination value to the environmentObject's value then change the value of the environmentObject in the modal view.

Here is a code explaining what I mean

import SwiftUI

class NavigationManager: ObservableObject{
    @Published private(set) var dest: AnyView? = nil
    @Published var isActive: Bool = false

    func move(to: AnyView) {
        self.dest = to
        self.isActive = true
    }
}

struct StackOverflow6: View {
    @State var showModal: Bool = false
    @EnvironmentObject var navigationManager: NavigationManager
    var body: some View {
        NavigationView {
            ZStack {
                NavigationLink(destination: self.navigationManager.dest, isActive: self.$navigationManager.isActive) {
                    EmptyView()
                }

                Button(action: {
                    self.showModal.toggle()
                }) {
                    Text("Show Modal")
                }
            }
        }
            .sheet(isPresented: self.$showModal) {
                secondView(isPresented: self.$showModal).environmentObject(self.navigationManager)
            }
    }
}

struct StackOverflow6_Previews: PreviewProvider {
    static var previews: some View {
        StackOverflow6().environmentObject(NavigationManager())
    }
}


struct secondView: View {
    @EnvironmentObject var navigationManager: NavigationManager
    @Binding var isPresented: Bool
    @State var dest: AnyView? = nil

    var body: some View {
        VStack {
            Text("Modal view")
            Button(action: {
                self.isPresented = false
                self.dest = AnyView(thirdView())
            }) {
                Text("Press me to navigate")
            }
        }
        .onDisappear {
            // This code can run any where but I placed it in `.onDisappear` so you can see the animation
            if let dest = self.dest {
                self.navigationManager.move(to: dest)
            }
        }
    }
}

struct thirdView: View {
    var body: some View {
        Text("3rd")
            .navigationBarTitle(Text("3rd View"))
    }
}

Hope this helps, if you have any questions regarding this code, please let me know.

like image 193
Muhand Jumah Avatar answered Oct 28 '25 19:10

Muhand Jumah



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!