How to add NavigationView to List in SwiftUI and show detail view using NavigationLink

In previous posts we learned how to create a List with custom rows and how to customize a List (using sections, header and footer). Today, we’re going to add a NavigationView to our List and implement a detail view for each row in the List using NavigationLink.

First, we need to embed our List in NavigationView and set its title using navigationBarTitle modifier. Entire code for the List should look like this:

import SwiftUI

struct Trail: Identifiable {
    var id = UUID()
    var name: String
    var location: String
    var distance: Double
}

struct TrailRow: View {
    var trail: Trail
    
    var body: some View {
        HStack {
            VStack(alignment: .leading) {
                Text(trail.name)
                Text(trail.location).font(.subheadline).foregroundColor(.gray)
            }
            Spacer()
            Text(String(format: "%.1f miles", trail.distance))
        }
    }
}

struct ContentView: View {
    let hikingTrails = [
        Trail(name: "Stanford Dish", location: "Palo Alto", distance: 3.9),
        Trail(name: "Edgewood", location: "Redwood City", distance: 3.2),
        Trail(name: "Mission Peak", location: "Fremont", distance: 7.1),
        Trail(name: "Big Basin", location: "Boulder Creek", distance: 4.3),
        Trail(name: "Alum Rock", location: "Milpitas", distance: 5.7),
    ]
    
    var body: some View {
        NavigationView {
            List(hikingTrails) { trail in
                TrailRow(trail: trail)
            }
            .navigationBarTitle("Hiking Trails")
        }
    }
}

Then, we need to create a detail view to represent each individual row (a trail):

struct DetailView: View {
    var trail: Trail
    
    var body: some View {
        VStack {
            Text(trail.name).font(.title)
            
            HStack {
                Text("\(trail.location) - \(String(format: "%.1f miles", trail.distance))")
            }
            
            Spacer()
        }
    }
}

Finally, we need to use NavigationLink in order to link each row of the List to the DetailView we just created. Do this by wrapping each TrailRow with NavigationLink and specifying its destination:

NavigationView {
    List(hikingTrails) { trail in
        NavigationLink(destination: DetailView(trail: trail)) {
            TrailRow(trail: trail)
        }
    }
    .navigationBarTitle("Hiking Trails")
}

The final effect should look like the images below. The List has a large title and with each row having a navigation arrow indicating that the user can tap on it to push a detail view.

SwiftUI List with NavigationView
Detail view for a row in SwiftUI List using NavigationLink

Related tutorials: