You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:45:04