NavigationSplitView crashes if I select an item in the sidebar after I removed other items

63 views Asked by At

My NavigationSplitView crashes if I select an item in the sidebar after I removed other items: Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1c44d488c)

How to reproduce:

The app crashes: Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1c44d488c)

It occurs if I use just Strings or Core Data objects (I tried with plain String because I thought it was maybe an issue with Core Data but it’s not apparently).

What is wrong? Is that a bug?

import SwiftUI

@main
struct FB_SwiftUI_NavigationSplitView_Delete_SelectApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

enum SelectionString: Hashable {
    case all
    case item(String)
}

struct ContentView: View {
    @State private var selectionString: SelectionString?
    @State private var strings: [String] = []

    var body: some View {
        NavigationSplitView {
            List(selection: $selectionString) {
                Section {
                    NavigationLink(value: SelectionString.all) {
                        Text("All")
                    }
                }
            
                Section {
                    ForEach(strings.sorted(), id: \.self) { string in
                        NavigationLink(value: SelectionString.item(string)) {
                            Text(string)
                        }
                    }
                }
            }
            .toolbar {
                ToolbarItem {
                    Button("Add") {
                        strings.append(UUID().uuidString)
                    }
                }
            }
        } detail: {
            if let selectionString {
                switch selectionString {
                case .all:
                    Text("All")
                
                case .item(let string):
                    Button(role: .destructive) {
                        if let index = strings.firstIndex(of: string) {
                            strings.remove(at: index)
                            self.selectionString = nil
                        }
                    } label: {
                        Text("Delete")
                    }
                }
            } else {
                Text("Select an item")
            }
        }
    }
}

enter image description here

1

There are 1 answers

1
Sweeper On

I suspect this is a SwiftUI bug. The problem can be reproduced on iOS, but not on macOS. If I replace the NavigationLinks with simple Texts, it works as expected:

Section {
    Text("All").tag(SelectionString.all)
}

Section {
    ForEach(strings.sorted(), id: \.self) { string in
        Text(string).tag(SelectionString.item(string))
    }
}

Putting them in the same section, switching the order of the sections, or putting another section after the ForEach section, all fixes the problem. This leads me to believe that this might be (at least partly) caused by the same bug as this other problem, which is also related to the last row of a List behaving weirdly.