1
votes

I'm trying to build a pretty simple layout with a sidebar and a detail view on iOS with SwiftUI. But it seems like it's not possible to have a large title in the detail view on the iPad. It should actually look like the Reminders app of Apple.

What I want (the blue text Reminders in the detail view): This is what I want, the text 'Reminders' is a large title in a detail view

However, in my own app, it doesn't work. I found this example by Apple about building lists and navigation: https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation

But it doesn't work there as well. Even if I set the title in the LandmarkDetail.swift like so:

VStack {
    MapView(coordinate: landmark.locationCoordinate)
        .frame(height: 300)

    CircleImage(image: landmark.image)
        .offset(x: 0, y: -130)
        .padding(.bottom, -130)

    VStack(alignment: .leading) {
        Text(landmark.name)
            .font(.title)

        HStack(alignment: .top) {
            Text(landmark.park)
                .font(.subheadline)
            Spacer()
            Text(landmark.state)
                .font(.subheadline)
        }
    }
    .padding()

    Spacer()
}
.navigationBarTitle(Text(verbatim: landmark.name), displayMode: .large)

I tested it on the iPhone and there it works. I also added another NavigationView in the detail but it only made the whole thing worse. I had a large title but the title appeared below another navigation bar so with a huge margin from the top.

2

2 Answers

1
votes

I did try to a similar way to keep the large title in both sides in split view but failed. So to do that I guess you can try to add a custom view in right. You can add NavigationView in HStack and can arrange views like belowscreenshot

Here is the code

    var body: some View {
        HStack{
        NavigationView {
        List(landmarkData) { landmark in
            NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
                LandmarkRow(landmark: landmark)
            }.isDetailLink(false)
        }
        .navigationBarTitle(Text("Landmarks"), displayMode: .large)
        }
        NavigationView {
            List(landmarkData) { landmark in
                NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
                    LandmarkRow(landmark: landmark)
                }.isDetailLink(false)
            }
            .navigationBarTitle(Text("Landmarks"), displayMode: .large)
        }
        NavigationView {
            LandmarkDetail(landmark: landmarkData[0])
            .navigationBarTitle(Text("Landmarks"), displayMode: .large)
        }
    }
}

Note: Right now it doesn't support large title on both the sides in iPad.

1
votes

With Xcode 11.1 the issue seems to be fixed. I was in contact with Apple regarding the issue. They said I should report the bug which is now not needed anymore.

I used the following code:

NavigationView {
    VStack {
        MapView(coordinate: landmark.locationCoordinate)
            .frame(height: 300)

        CircleImage(image: landmark.image)
            .offset(x: 0, y: -130)
            .padding(.bottom, -130)

        VStack(alignment: .leading) {
            Text(landmark.name)
                .font(.title)

            HStack(alignment: .top) {
                Text(landmark.park)
                    .font(.subheadline)
                Spacer()
                Text(landmark.state)
                    .font(.subheadline)
            }
        }
        .padding()

        Spacer()
    }
    .navigationBarTitle(Text(verbatim: landmark.name), displayMode: .large)
}
.navigationBarTitle("")
.navigationBarHidden(true)
.navigationViewStyle(StackNavigationViewStyle())

It's very important that you add a NavigationView itself around your detail screen. Otherwise, large title won't work. Just with that, you would end up with two navigation bars and a very large margin on top.

But when you use .navigationBarHidden(true) and (very important!!!) .navigationBarTitle("") on the navigation view itself, it seems to hide the first navigation bar and you end up with a layout that has a large title in the detail view without any additional margins or weird behavior.

Additional information: It is very important to understand that there is a distinction on where those rules apply. When you call navigation bar modifiers inside of a NavigationView it will apply the rules for the navigation bar of this navigation view. However, when you call it directly on the navigation view (like I did with the hide and empty title above) then those modifiers will target the next outer navigation bar.

Edit: Seems like Xcode 11.2 / newest iPadOS version you are required to add .navigationViewStyle(StackNavigationViewStyle()) to the inner navigation view. I've added that in the code above.