NavigationSplitView not working as shown in "What's new with SwiftUI" session

Hey guys

I'm trying to follow along with the WWDC session titled "What's new with SwiftUI". They say it's possible to have the detail view of a NavigationSplitView be determined based on a state variable by using the following code:

However, and I'm kinda going crazy here, this code does NOT work on iOS whatsoever, the view will remain the one determined by "default" Switch case. It works fine on macOS, but iOS (and iPadOS) simply will not change the detail view no matter what.

I have tried working around it for hours but it seems to boil down to the view never being redrawn... has anyone tried this? Is this just a iOS bug??

Accepted Reply

Of course right after I asked the question I notice this in the release notes 🤦‍♂️

Conditional views in columns of NavigationSplitView fail to update on some state changes. (91311311) Workaround: Wrap the contents of the column in a ZStack.

  • Nice find!! will help a lot of others!!

  • Thank you, I've been banging my head against this problem for like an hour

  • It's been two days for me LOL. I tried everything until I found this. Unfortunately, they still didn't fix it in Beta 3.

Replies

Of course right after I asked the question I notice this in the release notes 🤦‍♂️

Conditional views in columns of NavigationSplitView fail to update on some state changes. (91311311) Workaround: Wrap the contents of the column in a ZStack.

  • Nice find!! will help a lot of others!!

  • Thank you, I've been banging my head against this problem for like an hour

  • It's been two days for me LOL. I tried everything until I found this. Unfortunately, they still didn't fix it in Beta 3.

Thank you! I got exactly the same. I was building a simple list-detail interface with NavigationSplitView and wondering why it was not updating the detail contents. Wrapping the column content in ZStack helped.

Just in case others hit it, here’s my code.

struct Thing: Identifiable, Hashable {
    let id: UUID
    let name: String
}

struct ContentView: View {
    let things: [Thing]
    @State private var selectedThing: Thing?
    var body: some View {
        NavigationSplitView {
            List(things, selection: $selectedThing) { thing in
                NavigationLink(value: thing) {
                        Text("navlink: \(thing.name)")
                }
            }
        } detail: {
          // This is the ZStack wrapper, hopefully won’t be needed when 91311311 is fixed.
          ZStack {
            if let selectedThing {
              Text("There is a thing: \(selectedThing.name)")
            } else {
              Text("There is no thing.")
            }
          }
        }
    }
}

Not solving it for me, the view's constructor is getting called but neither the onAppear() nor task() is getting called

  • I'm in the same boat, no relief is had by wrapping the column in a ZStack. iPhone build works as expected, iPad only updates the detail view once, then no more. Detail view .onAppear is not accessed after the first update. Using release version of Xcode 14.2.

Add a Comment

I found that appending an .id modifier to the detail column resolved the problem for me:

         } detail: {

            if let selectedCocktail {

               CocktailDetailView(pCocktail: selectedCocktail)

                  .navigationTitle("(selectedCocktail.favorite ? "(profile.userData.favoriteCocktailsIcon.rawValue)" : "") (selectedCocktail.cocktailName ?? "")")

                  .id(selectedCocktail.id) //workaround }

  • Yes, thanks Andrew. Appending the 'id' element fixed it for me too, while the ZStack workaround suggested above did not.

  • Confirmed: .id modifier solved it for me.

  • This was the solution for me.. great thsnks

Hi Andrew, thank you very much for your workaround - finally I can get my Detail view to refresh correctly. ".onAppear" finally fires.

I've tried all the other suggestions above without success.

I'm a beginner in iOS App development and I've struggled with this problem for 3 days. I don't understand yet as to why it works, but that's for another day

Cheers