2

I’ve filed this bug with Apple (FB12119791) since I’m pretty sure it’s not a mistake in my code, but posting here both for posterity and to see if anyone has found a solution. It’s also hard to describe, so the attached code sample is probably a good place to start.

When conditionally rendering a row outside of a section alongside a section of rows in NavigationSplitView’s sidebar, an application crash can be consistently reproduced.

Steps to reproduce

  1. Create a SwiftUI view with a NavigationSplitView. For the split view’s sidebar, create a list with navigable elements and a conditionally-rendered, non-navigable element (i.e. a view that only renders when a boolean state value is true)
  2. Navigate into a navigable element’s destination, then back to the list
  3. Toggle the conditional state value off to hide the conditionally-rendered element
  4. Try to navigate into a navigable element’s destination again

Expected result

The navigation view should segue to the chosen navigable element’s destination

Actual result

The app (or Xcode preview) crashes at the app’s @main entry point

Code sample

import SwiftUI

fileprivate struct Item: Identifiable, Hashable {
    let id = UUID()
}

fileprivate let items = (0...10).map { _ in Item() }

struct ListSelectionConditionalViewCrashExample: View {
    @State var showConditionalView = true
    @State var selectedItem: UUID?
    
    var body: some View {
        NavigationSplitView {
            List(selection: $selectedItem) {
                Section {
                    Label("Tap a row in the navigable rows section below", systemImage: "1.circle")
                    Label("Return to this screen", systemImage: "2.circle")
                    Label("Toggle the control below **off**", systemImage: "3.circle")
                    Label("Tap a row in the navigable rows section below", systemImage: "4.circle")
                    Label("Observe the app crash", systemImage: "exclamationmark.circle")
                        .foregroundStyle(.red)
                    Text("Note this only happens when navigable and non-navigable rows appear in separate sections")
                    Toggle(isOn: $showConditionalView.animation()) {
                        Text("Render conditional view")
                    }
                } header: {
                    Text("Instructions")
                }
                
                if showConditionalView {
                    Text("Conditional view")
                }
                
                Section {
                    ForEach(items) { item in
                        Text(item.id.uuidString)
                            .tag(item.id)
                    }
                } header: {
                    Text("Navigable rows")
                }
            }
            .navigationTitle("Navigation List Crash")
        } detail: {
            if let selectedItem,
                 let item = items.first(where: { $0.id == selectedItem }) {
                Text(item.id.uuidString)
                    .navigationTitle("Detail View")
            } else {
                Text("No selection")
            }
        }
    }
}

struct ListSelectionConditionalViewCrashExample_Previews: PreviewProvider {
    static var previews: some View {
        ListSelectionConditionalViewCrashExample()
    }
}
Dan Eden
  • 1,494
  • 1
  • 11
  • 12
  • Confirm I can reproduce this. – malhal Apr 15 '23 at 16:28
  • Similar Behavior: [https://stackoverflow.com/questions/76450376/navigationsplitview-run-time-error-when-collapse-and-expand-sections](https://stackoverflow.com/questions/76450376/navigationsplitview-run-time-error-when-collapse-and-expand-sections) – Dinox Jun 12 '23 at 06:58

0 Answers0