I am making app where I have to be able to modify/delete data. I am using firebase so the original structure is more complex, but to show my problem I created test views. I am having hard time debugging issue with view dismissing itself. After deleting one item of nested array, it's dismissing my view, and I am not sure how to prevent that.
This is my model:
struct Object: Identifiable {
var id = UUID()
var name: String
var nestedObjects: [NestedObject]
}
struct NestedObject: Identifiable {
var id = UUID()
var name: String
}
This is my View Model:
class ViewModel: ObservableObject {
@Published var objects = [
Object(name: "1", nestedObjects: [
NestedObject(name: "1.1"),
NestedObject(name: "1.2"),
NestedObject(name: "1.3"),
NestedObject(name: "1.4"),
]),
Object(name: "2", nestedObjects: [
NestedObject(name: "2.1"),
NestedObject(name: "2.2"),
NestedObject(name: "2.3"),
NestedObject(name: "2.4"),
])
]
}
Content View:
struct ContentView: View {
@StateObject var vm = ViewModel()
var body: some View {
NavigationView {
List(vm.objects){ object in
NavigationLink {
SubView(object: object)
} label: {
Text(object.name)
}
}
}.environmentObject(vm)
}
}
And Nested View:
struct SubView: View {
let object: Object
@EnvironmentObject var vm: ViewModel
var body: some View {
List(object.nestedObjects) { nested in
HStack {
Text(nested.name)
Spacer()
Button {
let array = object.nestedObjects.filter({$0.id != nested.id})
vm.objects = vm.objects.filter({$0.id != object.id})
vm.objects.append(Object(name: object.name, nestedObjects: array))
} label: {
Image(systemName: "trash.fill")
}.buttonStyle(.borderless)
}
}
}
}
I really want the structure to stay because I know that I am overdoing here in this example but in main project I have Firestone listener and after reaching which object is modified I have to change him, and that's when it's being dismissed.
CodePudding user response:
The problem is happening because NavigationLink
depends on the Object
id
. When you create a new Object
by doing Object(name: object.name, nestedObjects: array)
, it has a new and different id
because of your definition of id
: var id = UUID()
One solution would be to make a copy of the Object
, replace the nested values, and then map
it back into the original array.
Note that this might be even easier if you chose to structure your Objects in a
Dictionarykeyed by
id` rather than an array, but that's certainly optional.
struct SubView: View {
let object: Object
@EnvironmentObject var vm: ViewModel
var body: some View {
List(object.nestedObjects) { nested in
HStack {
Text(nested.name)
Spacer()
Button {
var copy = object
copy.nestedObjects = object.nestedObjects.filter { $0.id != nested.id }
vm.objects = vm.objects.map { $0.id == copy.id ? copy : $0 }
} label: {
Image(systemName: "trash.fill")
}.buttonStyle(.borderless)
}
}
}
}