SwiftUI TabVIew Faulting while switching between Tabs

I'm working on a SwiftUI based application for MacOS. I have a TabView component with two child Tab components. These Tab components display a List, each derived from an array of elements.

While the application is running, clicking on the tabs in the TabView should switch between the views of different Lists. What I'm experiencing is that switching between the tabs causes a FAULT. With errors:

Row index 1 out of row range (numberOfRows: 1) for <SwiftUI.SwiftUIOutlineListView: 0x1299d2000>

Followed by:

(
	0   CoreFoundation                      0x000000019e096e80 __exceptionPreprocess + 176
	1   libobjc.A.dylib                     0x000000019db7ecd8 objc_exception_throw + 88
	2   AppKit                              0x00000001a1c744e8 -[NSTableRowData _availableRowViewWhileUpdatingAtRow:] + 0
	3   SwiftUI                             0x00000001cd8953f4 $s7SwiftUI0A17UIOutlineListViewC11removeItems2at8inParent13withAnimationy10Foundation8IndexSetV_ypSgSo07NSTableeL7OptionsVtF + 1232
  ...
  ...
)

And finally:

FAULT: NSTableViewException: Row index 1 out of row range (numberOfRows: 1) for <SwiftUI.SwiftUIOutlineListView: 0x1299d2000>; (user info absent)

This error happens when switching between the two tabs, defined thusly:

@main
struct MyApp: App {
    @State var rootDirectory: URL
    @State var selectedItem: URL
    @State var projectNavItems: [NavigationItem] = []
    @State var jotNavItems: [NavigationItem] = []
    @State var importerIsPresented: Bool = false
    let fileManager = FileManager.default

    init() {
        rootDirectory = URL(string: FileManager.default.currentDirectoryPath)!
        selectedItem = URL(string: FileManager.default.currentDirectoryPath)!.appendingPathComponent("README.md")
    }

    var body: some Scene {
        WindowGroup {
            NavigationSplitView {
                TabView {
                    Tab("Projects", systemImage: "tray.and.arrow.down.fill") {
                        List(projectNavItems, selection: $selectedItem) {
                            // Changing this NavigationLink line to Text($0.title) makes no difference
                            NavigationLink($0.title, value: $0.id)
                        }
                    }

                    Tab("Jots", systemImage: "tray.and.arrow.up.fill") {
                        List(jotNavItems, selection: $selectedJot) {
                            // Can be written as Text($0.title) with no change in behavior
                            NavigationLink($0.title, value: $0.id)
                        }
                    }
                }

            } detail: {
                Editor(for: selectedItem)
            }
            .fileImporter(
                isPresented: $importerIsPresented,
                allowedContentTypes: [UTType.folder],
                allowsMultipleSelection: false
            ) { result in
                // Code that gets a security scoped resource and populates the
                // projectNavItems: [NavItem] and jotNavItems: [NavItem]
                // arrays
            }
        }
        .commands(content: {
            CommandGroup (before: .newItem) {
                Button("Open Journal...") {
                    importerIsPresented.toggle()
                }
            }
        })
    }
}

The error only happens when both Tab views are populated by a List. If the Tab view have different child components, say a List, and a ForEach of Text components, switching between the tabs doesn't produce this error. List views with Text child components also produce this error.

Here are screenshots of the running application

Once the user selects a directory, we see the first Tab > List component populated by contents from the projectNavItems array:

Clicking on the 'Jots' tab switches to the appropriate tab and correctly lists the items in the jotNavItems array, except there are additional lines, seemingly showing that there's an issue.

Clicking back on the 'Projects' tab switches back, but now the List shows only one of the items from the projectNavItems array.

Finally, clicking on 'Jots' again causes the errors to print in the console and interactivity with the tab components ceases. Last screenshot is representative of this state as the application FAULTS.

This seems like a bug in SwifUI, wondering what workarounds I might be able to implement.

I can provide the full backtrace, I cropped it for content length.

From the snippet you posted, I'd suggest you don't nest a TabView as the sidebar content of your NavigationSplitView. Both are top level navigation containers, and could have conflicting behaviors when embedded. Plus `TabView' now has an updated appearance. see Enhancing your app’s content with tab navigation

All that said, embedding the TabView isn't the intended way the API was designed to be used and would be a reciepe for unexpected behaviors.

From your code snippet, You might need a Toggle instead of a Tabview to toggles between the various states and views.

Thanks for the reply DTS Engineer!

Moving the TabView out of the NavigationSplitView element, making it the topmost element in the WindowGroup produces the same results, ie FAULT due to index out of range while switching between the tabs.

I still believe there is an issue with the API. That said, now I openly wonder how one may achieve similar results to Xcode's sidebar.

SwiftUI TabVIew Faulting while switching between Tabs
 
 
Q