I'm trying to update an older app to use the new NavigationSplitView and NavigationLink, but trying to wrap my head around the proper way to do it when the sidebar has a hierarchy of child objects and I want to update the detail view from a distant child object. For example, based on the WWDC2022 example project Navigation Cookbook I tried the following and it didn't work:

TestApp.swift

@main

struct TestApp: App {
  @StateObject var appState = AppState()

  var body: some Scene {
    WindowGroup {

      NavigationSplitView {
         ProjectListView()
      } detail: {
        if let chapter = appState.chapter {
          ChapterDetailView(chapter: chapter)
        } else {
          Text("Pick a Chapter")
        }
      }
    }
  }
}

ChapterListView.swift < A distant (3 levels down) sibling of ProjectListView()

List(selection: $appState.chapter) {
  ForEach(chapters) { chapter in
    NavigationLink(chapter.title ?? "A Chapter", value: chapter)
  }
}

appState.swift

class AppState: ObservableObject {
  @Published var chapter: Chapter?
}

I'm sure I'm just not understanding the basics of how the new way of doing navigation works. Yes, I am targeting iOS16

1

There are 1 best solutions below

0
tharris On BEST ANSWER

This is a known bug in beta 1. To workaround, the logic in the detail section needs to be wrapped in a ZStack. From 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. TestApp works if changed to this:

@main

struct TestApp: App {
  @StateObject var appState = AppState()

  var body: some Scene {
    WindowGroup {

      NavigationSplitView {
         ProjectListView()
      } detail: {
// Wrap in a ZStack to fix this bug
       ZStack {
        if let chapter = appState.chapter {
          ChapterDetailView(chapter: chapter)
        } else {
          Text("Pick a Chapter")
        }
       }
      }
    }
  }
}