How to handle adding and removing items from NavigationSplitView

Hello, I'm new to app development and have a question that I have been searching all over the place to find an answer to. I have followed Apple's own guides and don't know how to move around the strange issue I am experiencing.

I have a project using NavigationSplitView and have the code setup so that it navigates through an array of items. The two issues I am experiencing that I hope to find some help with are:

  1. I would like to be able to have my add button, instead of presenting a sheet, just navigate to a new item within the NavigationSplitView. This would be more natural for the type of data application I have created. At this time I create the item with a .sheet modifier and then the item is created and added to the array. However, I then have to tap on the newly created item to get it to be selected. Is this how SwiftUI should be working?
  2. Whenever an item is deleted from the list, and it was the last item selected or the last item in the array, the NavigationSplitView will continue showing that remaining item. The only way to get it to show an empty content screen is to force close the application and then reopen it.

Since this is my first time posting, I'm not sure what information would be helpful, but would be happy to provide anything which could be of assistance. :-)

Hi @erfinb ,

  1. I would like to be able to have my add button, instead of presenting a sheet, just navigate to a new item within the NavigationSplitView.

After appending the object in your add button, programmatically set the selection variable to be the last item in the array. (example below)

.

  1. Whenever an item is deleted from the list, and it was the last item selected or the last item in the array, the NavigationSplitView will continue showing that remaining item.

What you need to do here is use the onDelete modifier. You first need to check for the first item that you're deleting and then check if that item is equal to the current selection. If so, set the selection to nil. Then, remove the item from the array.

Here is a full code snippet showing both:

import SwiftUI

struct ContentView: View {
    @State private var items: [Int] = [1, 2, 3, 4, 5]
    @State private var selection: Int?
    
    var body: some View {
        NavigationSplitView {
            List(selection: $selection) {
                ForEach($items, id: \.self) { $item in
                    Text(item.description)
                }
                .onDelete { itemsToDelete in
                    if let itemToDelete = itemsToDelete.first {
                        if items[itemToDelete] == selection {
                            selection = nil
                        }
                    }
                    items.remove(atOffsets: deleted)
                }
            }
            .toolbar {
                ToolbarItem {
                    Button("add") {
                        items.append(6)
                        selection = items.last
                    }
                }
            }
        } detail: {
            if let selection {
                Text(selection.description)
            }
            else {
                Text("none")
            }
            
        }
            
    }
}

@Vision Pro Engineer

How would you select the last item that is being stored with SwiftData?


@Environment(\.modelContext) private var modelContex
```t
    @Query private var applicants: [Applicant]
    @State private var newApplicant: Applicant?
    @State private var selection: Applicant?
///
if !applicants.isEmpty {
                List (selection: $selection) {
                    ForEach(applicants) { applicant in
                        NavigationLink {
                            ApplicantView(applicant: applicant)
///
private func addApplicant() {
        withAnimation {
            let newItem = Applicant()
            modelContext.insert(newItem)
            newApplicant = newItem
            selection = applicants.last
        }
    }
'''

I have it setup this way but the behavior has not changed. :-) Thank you again for your help!

@erfinb , when you click the add button in your navigation split view, it runs addApplicant(), right?

I'd expect a new applicant object to be created & added to the end of the applicants array. On the line before you do selection = applicants.last, can you do print(applicants.last) to ensure that it's actually there? Than we can check if the selection is being set to the correct item. I expect that value to be the Applicant you just created, so let me know if it's not.

If it is the Applicant that you just created, can you give me some more information about how the rest of your app is working? Can you show me how your NavigationSplitView is set up?

Best, Sydney

How to handle adding and removing items from NavigationSplitView
 
 
Q