How to display default detail in NavigationSplitView after deleting an item — on iPad

Viewed 23

I have a NavigationSplitView (SwiftUI 4, iOS16), list of items in the left part, detail on right. When I run the application, no item selected, it displays "Select item" on the right (detail part). I select an item and it displays item detail on right. So far so good.

Now I delete the item on the left by swiping to the left... but the right part still displays the deleted item detail.

Is there any way to get right part go back to the not-selected detail?

Please notice this behaviour can be observed on iPad only, not on iPhone, as iPhone does not display both parts of NavigationSplitView together.

import SwiftUI

struct ContentView: View {
    @State var items = ["item 1", "item 2", "item 3", "item 4"]
    var body: some View {
        NavigationSplitView {
            List {
                ForEach(items, id: \.self) { item in
                    NavigationLink(destination: Text(item)) {
                        Text(item)
                    }
                }
                .onDelete(perform: { offsets in
                    items.remove(atOffsets: offsets)
                })
            }
        } detail: {
            Text("Select item")
        }
    }
}
1 Answers

Bind your selection with List using @State property and also you don't require to add NavigationLink, NavigationSplitView automatically show detail for the selected list item.

Now if you remove the selected item from the list then after deleting it from the array simply set nil to the selection binding of List.

struct ContentView: View {
    @State var items = ["item 1", "item 2", "item 3", "item 4"]
    @State private var selection: String?
    
    var body: some View {
        NavigationSplitView {
            List(selection: $selection) {
                ForEach(items, id: \.self) { item in
                    Text(item)
                }
                .onDelete(perform: { offsets in
                    items.remove(atOffsets: offsets)
                    guard selection != nil, !items.contains(selection!) else { return }
                    selection = nil
                })
            }
        } detail: {
            if let selectedItem = selection {
                Text(selectedItem)
            }
            else {
                Text("Select item")
            }
        }
    }
}

Suggest you to check the Apple documentation of NavigationSplitView for more details.

Related