eleethesontai
eleethesontai

Reputation: 546

ForEach onDelete Mac

I am trying to figure out how to delete from an array in swiftui for Mac. All the articles that I can find show how to do it the UIKit way with the .ondelete method added to the foreach. This is does not work for the Mac because I do not have the red delete button like iOS does. So how do I delete items from an array in ForEach on Mac. here is the code that I have tried, which gives me the error

Fatal error: Index out of range: file

import SwiftUI

struct ContentView: View {

    @State var splitItems:[SplitItem] = [
        SplitItem(id: 0, name: "Item#1"),
        SplitItem(id: 1, name: "Item#2")
    ]

    var body: some View {
        VStack {
            Text("Value: \(self.splitItems[0].name)")
            ForEach(self.splitItems.indices, id:\.self) { index in
                HStack {
                    TextField("Item# ", text: self.$splitItems[index].name)
                    Button(action: {self.removeItem(index: index)}) {Text("-")}
                }
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }

    func removeItem(index:Int) {
        self.splitItems.remove(at: index)
    }

}

struct SplitItem:Identifiable {
    var id:Int
    var name:String
}

Upvotes: 0

Views: 914

Answers (2)

eleethesontai
eleethesontai

Reputation: 546

so I was able to find the answer in this article,

instead of calling array.remove(at) by passing the index from the for loop call it using array.FirstIndex(where).

Upvotes: 0

Aleksey Potapov
Aleksey Potapov

Reputation: 3783

Your ForEach code part is completely correct. The possible error source could be the line Text("Value: \(self.splitItems[0].name)") - after deleting all items this will definitely crash.

The next assumption is the VStack. After Drawing a view hierarchy it will not allow to change it. If you replace the VStack with Group and the next code will work:

var body: some View {
    Group {
        if !self.splitItems.isEmpty {
            Text("Value: \(self.splitItems[0].name)")
        } else {
            Text("List is empty")
        }
        ForEach(self.splitItems.indices, id:\.self) { index in
            HStack {
                TextField("Item# ", text: self.$splitItems[index].name)
                Button(action: {self.removeItem(index: index)}) {Text("-")}
            }
        }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
}

Upvotes: 1

Related Questions