Nav Mistake


« Kimmy's Crepes

View Builder »

One of my favorite things that Julia Child did during cooking demonstrations was point to her mistakes and how she could fix them.

That's what I'm going to do for you today - though the milieu is SwiftUI.

Here's a simple example of a ContentView that presents a List of three Text cells labeled "Main 1", "Main 2", and "Main 3".

ContentView.swift struct ContentView: View { var body: some View { NavigationView { List(1..<4){int in NavigationLink( destination: DetailView(source: int)){ Text("Main \(int)") } }.navigationTitle("Main") } } }

I've also provided a title that sits in the nav bar and each row links to a detail view. When I launch it on the iPhone simulator it looks like this.

The table view containing rows Main 1, Main 2, and Main 3 with nav title Main

Here's the DetailView that we navigate to by providing an Int. Note - it contains my error.

DetailView.swift struct DetailView: View { let source: Int var body: some View { // this is not correct NavigationView { Text("Detail for row \(source)!") } .navigationTitle("Detail \(source)") } }

I knew better than that. (It's ok if you don't see it yet - it essentially works the same as it does on UIKit which I've been coding for for more than a decade).

And yet I typed it in and checked it on the iPhone. When I tapped a row in the ContentView I navigated to the DetailView as I expected and saw this - which is both correct and what I expected.

The detail view containing Detail for row 1 with nav title Detail 1

Now I was actually on my way to building a different example which I'll show you in the next post. But before I moved on I decided to push this example to a device and for some reason (thank goodness) I chose my iPad mini.

My mistake was on full display. We can actually see this error in the iPhone simulator rotated into landscape. Here's the ContentView.

The detail view is empty

I tap on the first row to show the first detail view on the right side and it's not what I see. Instead I see this back button on the left side.

The detail is empty there's a back button on the left

I tap the back button. The good news is that I see the detail view. The bad news is that I see it on the left portion of the screen.

The detail view on the left side of the screen - the right side is empty.

Sigh. A Nav View is a container view. We think of it as a stack of views. Navigating in pushes the new view on top of the stack and navigating out pops the departing view off. The detail view shouldn't be wrapped in it's own nav view.

DetailView.swift struct DetailView: View { let source: Int var body: some View { NavigationView { Text("Detail for row \(source)!") } .navigationTitle("Detail \(source)") } }

And now, of course, we get the behavior we want in landscape and portrait. Here's the landscape view after we select the first row and navigate back to main..

The main view on left and on right Detail for row 1 with nav title Detail 1

Just wanted you to know it happens to all of us.