WWDC23 SALE: Save 50% on all my Swift books and bundles! >>

Pushing new views onto the stack using NavigationLink

Paul Hudson    @twostraws   

SwiftUI’s NavigationView shows a navigation bar at the top of our views, but also does something else: it lets us push views onto a view stack. In fact, this is really the most fundamental form of iOS navigation – you can see it in Settings when you tap Wi-Fi or General, or in Messages whenever you tap someone’s name.

This view stack system is very different from the sheets we’ve used previously. Yes, both show some sort of new view, but there’s a difference in the way they are presented that affects the way users think about them.

Let’s start by looking at some code so you can see for yourself. If we wrap the default text view with a navigation view and give it a title, we get this:

struct ContentView: View {
    var body: some View {
        NavigationView {
            Text("Hello, world!")
                .padding()
            .navigationTitle("SwiftUI")
        }
    }
}

That text view is just static text; it’s not a button with any sort of action attached to it. We’re going to make it so that when the user taps on “Hello, world!” we present them with a new view, and that’s done using NavigationLink: give this a destination and something that can be tapped, and it will take care of the rest.

One of the many things I love about SwiftUI is that we can use NavigationLink with any kind of destination view. Yes, we can design a custom view to push to, but we can also push straight to some text.

To try this out, change your view to this:

NavigationView {
    NavigationLink {
        Text("Detail View")
    } label: {
        Text("Hello, world!")
            .padding()
    }
    .navigationTitle("SwiftUI")
}

Now run the code and see what you think. You will see that “Hello, world!” now looks like a button, and tapping it makes a new view slide in from the right saying “Detail View”. Even better, you’ll see that the “SwiftUI” title animates down to become a back button, and you can tap that or swipe from the left edge to go back.

So, both sheet() and NavigationLink allow us to show a new view from the current one, but the way they do it is different and you should choose them carefully:

  • NavigationLink is for showing details about the user’s selection, like you’re digging deeper into a topic.
  • sheet() is for showing unrelated content, such as settings or a compose window.

The most common place you see NavigationLink is with a list, and there SwiftUI does something quite marvelous.

Try modifying your code to this:

NavigationView {
    List(0..<100) { row in
        NavigationLink {
            Text("Detail \(row)")
        } label: {
            Text("Row \(row)")
        }
    }
    .navigationTitle("SwiftUI")
}

When you run the app now you’ll see 100 list rows that can be tapped to show a detail view, but you’ll also see gray disclosure indicators on the right edge. This is the standard iOS way of telling users another screen is going to slide in from the right when the row is tapped, and SwiftUI is smart enough to add it automatically here. If those rows weren’t navigation links – if you comment out the NavigationLink line and its closing brace – you’ll see the indicators disappear.

Save 50% in my WWDC23 sale.

SAVE 50% To celebrate WWDC23, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

BUY OUR BOOKS
Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 4.7/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.