3

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

tharris
  • 2,192
  • 2
  • 13
  • 14
  • Placing of StateObject inside WindowGroup closure is senseless. See that WWDC session one more time and then review code for it. – Asperi Jun 11 '22 at 18:08
  • @Asperi Sorry, copy and paste error. I fixed it. I am reviewing code for that session and this is very similar to what they do. The only big difference (that I can see) is that I'm trying to update the StateObject from a distant child. All of their code is included at the top level. – tharris Jun 11 '22 at 18:16

1 Answers1

4

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")
        }
       }
      }
    }
  }
}
tharris
  • 2,192
  • 2
  • 13
  • 14