SwiftUI使用swipeActions与confirmationDialog删除List条目时出现误删问题
问题原因
- 你将
confirmationDialog修饰符直接加在了List循环内的每个Cell上,且所有Cell共用同一个布尔类型的@State变量isShowingDeleteActions控制弹窗显隐。 - 当你触发某一个Cell的删除操作把
isShowingDeleteActions设为true时,SwiftUI会刷新整个List视图,List的Cell复用机制会导致弹窗闭包内捕获的item值被替换为其他当前可见Cell的对应条目,最终出现删除目标不匹配的问题。
修复方案
将控制弹窗的状态改为存储待删除的条目本身,同时把confirmationDialog修饰符移到List外层,避免受Cell复用影响,修复后的代码如下:
struct ConversationsSection: View { // 替换原布尔状态,存储当前待删除的条目 @State private var itemToDelete: String? = nil let items = ["One", "Two", "Three", "Four", "Five"] var body: some View { List(items, id: \.self) { item in Text(item) .swipeActions(edge: .trailing) { Button(role: .destructive) { // 点击删除时记录待删除的条目 itemToDelete = item print("Trying to delete: " + item) } label: { Label("Delete", systemImage: "trash") } } } // 弹窗移到List外层,通过可选值绑定控制显隐,直接获取待删除目标 .confirmationDialog("Delete item?", isPresented: Binding( get: { itemToDelete != nil }, set: { newValue in if !newValue { itemToDelete = nil } } ), presenting: itemToDelete) { target in Button("Confirm Delete", role: .destructive) { print("Actually deleting: " + target) itemToDelete = nil } } } }
修改后弹窗会直接使用你存入状态的目标条目,不会再受Cell复用的干扰,删除的条目会和你滑动选中的条目完全一致。
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

