Learn Courses My Dashboard

UIKit view transitions in SwiftUI

Hi, I am working on a simple project in swiftUI and have a question which I feel should have an easy answer yet I cannot seem to find one anywhere.

I would like to use a simple button, one that I can configure anywhere, to transition from the current view to another view. Obviously in SwiftUI there are the NavigationView and NavigationLink properties to do this seamlessly but they come with things like navigation titles, back buttons (both of which I’m aware you can hide) and I’m not sure how the data storage for these views works on a device.

I can create this view switching functionality by simply removing the back button and navigation bars and just having one view navigate to the other, then that view has a button that navigates back (but its not really “back” its more foreword to the previous view, if that makes sense), but this seems quite dirty as I’m not sure if there is a bunch of data on the previous views being added up as you click back and fourth.

I’ve done a little of Chris’s stuff with UIKit and I know you can simply make a button function transition to another one of your views, stackoverflow always just tells me stuff about the nav-view and nav-link, but there must be another way. Any help would be greatly appreciated, I’m quite new evidently but SwfitUI is very interesting to me. Thx!

The best would be if I could add a modifier to a button like “.navigationLinkBackButton” to make the functionality of the button the same as the “< Back” link

The way you present another view from a Button press is along the lines of this:

Declare a State boolean which is the trigger to show the view as a result of the button press. ie:

@State private var isShowingView = false

In your button action change that to true. ie:

isShowingView = true

Assuming that you have already written the code for the View you want to present, here are a couple of options available to you in order to present that View.

  1. Using a .sheet() modifier which will present the View Modally such that it slides up into view. You can dismiss the View by simply dragging it down or you can configure a button in that view, or some other trigger, to dismiss it.
  2. Using a .fullScreenCover() modifier which will present a view that covers the existing view. A method must be employed to dismiss the View to return to the previous View.

Here is some sample code to show you how the two different methods work:

struct ContentView: View {
    @State private var isShowingModalView = false
    @State private var isShowingFullScreenCover = false

    var body: some View {
        VStack(spacing: 30) {
            Text("Content View!")

            Button(action: {
                isShowingModalView = true
            }) {
                Text("Present Modal View")
            }

            Button(action: {
                isShowingFullScreenCover = true
            }) {
                Text("Present Full Screen Cover")
            }
        }
        .sheet(isPresented: $isShowingModalView, content: {
            SecondView()
        })
        .fullScreenCover(isPresented: $isShowingFullScreenCover, content: {
            SecondView()
        })
    }
}

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

struct SecondView: View {
    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        ZStack {
            Color(.yellow)
                .edgesIgnoringSafeArea(.all)
            VStack {
                HStack {
                    Spacer()
                    Button("Dismiss") {
                        presentationMode.wrappedValue.dismiss()
                    }
                    .padding([.top, .trailing], 10)
                }
                Spacer()
                Text("Second View")
                Spacer()
            }
        }
    }
}

Thanks Chris, this definitely helps, it still feels like these methods preserve some kind of view hierarchy? Like what if I wanted two views at the same “level” where pressing the button completely destroys the current view and presents a different one, instead of sliding up some cover sheet or wrapping the current view in a different one.

What you are suggesting doesn’t make any sense to me at the moment so if I have an understanding of what the purpose of your App is then perhaps I can come up with an alternative approach

Can you describe what you are trying to achieve in your App.