2

I try to implement a dynamic created list into an tabview in SwiftUI using an EnvironmentObject and a Binding (which may not be needed in the example-code below but it is in my real project) for the SubView of the row.

The list itself (add item, delete item) is working fine as well as the switch to the other "page" of the tabview. But if you are deleting the last item of the list, and only the last (if you are deleting the first one or any item between it also works fine) the app crashes with the Error: "Thread 1: Fatal error: Index out of range" as soon you are trying to switch to the other tab after deleting this item.

Heres the (example)-code:

import SwiftUI

struct PickerRowData: Equatable, Identifiable, Hashable  {
    var id = UUID()
    var pickerValueString = ""
}

class GlobalStates: ObservableObject, Identifiable {
    @Published var pickerRowData = [PickerRowData]()

    var id = UUID()
}

struct MeasurePickerRow: View, Identifiable {
    @Binding var pickerRowData: PickerRowData
    var id = UUID()

    var body: some View {
        return VStack {
            Text("Just a test. ID: \(pickerRowData.id)")
        }
    }
}

struct MeasurePickerView: View {
    @EnvironmentObject var globalStates: GlobalStates

    var body: some View {
        return NavigationView {
            List {
                ForEach(self.globalStates.pickerRowData) { rowData in
                    MeasurePickerRow(pickerRowData: self.$globalStates.pickerRowData[self.globalStates.pickerRowData.lastIndex(of: rowData) ?? 0])
                }
                .onDelete(perform: deleteMeasurePicker)
            }
            .listStyle(GroupedListStyle())
            .padding(0)
            .navigationBarTitle(Text("Input"), displayMode: .inline)
            .navigationBarItems(
                trailing: HStack {
                    Button(action: {
                        self.globalStates.pickerRowData.append(PickerRowData())
                    }) {
                        Image(systemName: "gauge.badge.plus")
                    }
                })
        }
    }
    func deleteMeasurePicker(at offsets: IndexSet) {
        self.globalStates.pickerRowData.remove(atOffsets: offsets)
    }
}

struct ContentView: View {
    var body: some View {
        TabView {
            MeasurePickerView()
                .tabItem {
                    Image(systemName: "gauge")
                    HStack {
                        Text("Tab 1")
                    }
            }
            Text("Tab 2 View")
                .tabItem {
                    Image(systemName: "equal.circle")
                    HStack {
                        Text("Tab 2")
                    }
            }
        }
    }
}

Did I miss something? I'm quite new in SwiftUI (and Swift) so I hope someone has a hint.

Regards, DZ

deimoszero
  • 21
  • 1

0 Answers0