SwiftUI问题:更新嵌套数组后如何防止视图自动返回
解决嵌套数组元素删除后视图自动返回问题
你的问题出在删除嵌套元素时的对象更新方式:你先将原Object从数组中过滤移除,再创建一个新的Object实例添加回去。由于SwiftUI的NavigationLink依赖Identifiable的id追踪导航状态,当原对象被从数组中移除时,SwiftUI会判定对应的导航目的地已失效,因此自动弹出当前子视图。
修改方案
不需要删除原对象再重建,直接修改数组中对应对象的nestedObjects属性即可,保证对象的id不变,SwiftUI就会识别为同一对象的属性更新,不会触发导航栈弹出。
- 在ViewModel中添加修改方法:
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"), ]) ] // 添加方法修改嵌套数组 func removeNestedObject(from objectId: UUID, nestedId: UUID) { guard let objectIndex = objects.firstIndex(where: { $0.id == objectId }) else { return } var updatedObject = objects[objectIndex] updatedObject.nestedObjects.removeAll { $0.id == nestedId } objects[objectIndex] = updatedObject } }
- 修改子视图的按钮动作:
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 { vm.removeNestedObject(from: object.id, nestedId: nested.id) } label: { Image(systemName: "trash.fill") }.buttonStyle(.borderless) } } } }
Firestore监听器场景适配
主项目中Firestore监听器触发对象修改时,同样遵循这个逻辑:不要直接删除原对象再添加新的Firestore返回对象,而是找到本地数组中对应id的对象,只更新需要修改的属性(比如nestedObjects或其他字段)。这样既保证数据同步,又不会触发导航栈的异常弹出。
内容的提问来源于stack exchange,提问作者green8
相关产品推荐
相关产品推荐

