Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you switch views without having a navigationView or an popover?

Tags:

swiftui

I am trying to change a view without having something over it like when you used segue in swift. But the only solution I came up with is to have a navigation bar navigationBar or a popover.

struct view1: View {

    var body: some View{

        Button(action: {
//          go to view2``
        }) {
            Text("press")
        }

    }
}
struct view2: View {

    var body: some View{
       Text("yeay")

    }
}
like image 742
HUGO FERRARI Avatar asked Oct 25 '19 14:10

HUGO FERRARI


2 Answers

If you just want to hide the navigation bar it's easy:

import SwiftUI

struct View2: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

    var body: some View {
        VStack {
            Button(action: {
                self.presentationMode.wrappedValue.dismiss()
            }) {
                Text("POP")
            }
        }
        .navigationBarTitle("")
        .navigationBarBackButtonHidden(true)
        .navigationBarHidden(true)
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: View2()) {
                Text("PUSH")
                    .navigationBarTitle("")
                    .navigationBarHidden(true)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

If you, instead, want to get rid of the NavigationView and NavigationLink views you have to implement your own custom navigation. It's a little more complicated. The following is just a simple example of a push/pop transition between two views.

import SwiftUI

struct View2: View {
    @Binding var push: Bool

    var body: some View {
        ZStack {
            Color.yellow
            Button(action: {
                withAnimation(.easeOut(duration: 0.3)) {
                    self.push.toggle()
                }
            }) {
                Text("POP")
            }
        }
        .edgesIgnoringSafeArea(.all)
    }
}

struct View1: View {
    @Binding var push: Bool

    var body: some View {
        ZStack {
            Color.green
            Button(action: {
                withAnimation(.easeOut(duration: 0.3)) {
                    self.push.toggle()
                }
            }) {
                Text("PUSH")
            }
        }
        .edgesIgnoringSafeArea(.all)
    }
}

struct ContentView: View {
    @State private var push = false

    var body: some View {
        ZStack {
            if !push {
                View1(push: $push)
                    .transition(.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .leading)))
            }

            if push {
                View2(push: $push)
                    .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .trailing)))
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
} 
like image 162
matteopuc Avatar answered Sep 20 '22 07:09

matteopuc


Anyone coming to this later might find this to be of interest; in short, shove a hunk of data into @environment, tickle that with a button push in whatever view you want, and since it's at the very top of the overall application stack, it forces a redraw, which acts like a full view navigation, without the potential lost memory and orphaned or lost objects of the whole push/pop navigation view silliness.

It's still a little more "single page app"-ey than I'd like, but since SwiftUI is so crippled in its navigation thoroughness, it'll do nicely.

Not my site, not my link, not my tutorial, and it's buried way down in the list of hits when searching, which is a shame; this is the closest to what many are looking for. IMO, this should be baked into SwiftUI as a first class operation, and made less workaround-ey.

https://blckbirds.com/post/how-to-navigate-between-views-in-swiftui-by-using-an-environmentobject/

like image 27
ChrisH Avatar answered Sep 19 '22 07:09

ChrisH