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

如何防止弹出确认对话框时可选择List的选中状态被重置?

SwiftUI可选择List弹出确认对话框时选中状态被重置的解决方法

在Xcode 16 beta 4、iOS 18环境下,使用带多选功能的List时,点击删除按钮弹出confirmationDialog后,List的选中状态会被自动清空(selection变为空Set),即便将confirmationDialog附加到List本身上,该问题依然存在。

解决思路与代码实现

核心思路是手动控制编辑模式,避免系统自动退出编辑状态导致选中项丢失,同时暂存选中状态确保对话框操作时使用的是弹出前的选中内容:

import SwiftUI

struct ContentView: View {
    @State private var elements: Set<UUID> = [.init(), .init(), .init()]
    @State private var selection: Set<UUID> = []
    @State private var tempSelection: Set<UUID> = [] // 暂存弹出对话框前的选中项
    @State private var isConfirmationDialogPresented: Bool = false
    @State private var isEditing = false // 手动控制编辑模式
    
    var body: some View {
        NavigationStack {
            List(
                elements.sorted(),
                id: \.self,
                selection: $selection
            ) { element in
                Text(String(describing: element)).lineLimit(1)
            }
            // 手动绑定编辑模式,替代系统默认的EditButton自动管理
            .environment(\.editMode, .constant(isEditing ? .active : .inactive))
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    // 自定义编辑/完成按钮
                    Button(isEditing ? "Done" : "Edit") {
                        isEditing.toggle()
                        // 仅在退出编辑时清空选中状态
                        if !isEditing {
                            selection.removeAll()
                        }
                    }
                }
                ToolbarItem(placement: .bottomBar) {
                    Button(
                        "Delete \(selection.count) element(s)",
                        role: .destructive,
                        action: {
                            // 弹出对话框前先暂存当前选中项
                            tempSelection = selection
                            isConfirmationDialogPresented = true
                        }
                    )
                    .disabled(selection.isEmpty)
                    .confirmationDialog(
                        "Delete \(tempSelection.count) elements(s)",
                        isPresented: $isConfirmationDialogPresented,
                        actions: {
                            Button("Delete \(tempSelection.count) element(s)", role: .destructive) {
                                // 使用暂存的选中项执行删除操作
                                elements = elements.subtracting(tempSelection)
                                // 删除后同步更新当前选中状态
                                selection.subtract(tempSelection)
                            }
                        },
                        message: {
                            Text("确定要删除这些项吗?")
                        }
                    )
                }
            }
        }
    }
}

关键说明

  1. 手动控制编辑模式:通过isEditing变量和environment(\.editMode)绑定,完全接管编辑状态的切换逻辑,避免系统在弹出对话框时自动退出编辑模式,从而防止选中状态被清空。
  2. 暂存选中状态:在触发对话框前将selection的值存入tempSelection,确保对话框中的删除操作基于弹出前的选中项执行,删除完成后再同步更新selection,保持界面状态一致性。

内容的提问来源于stack exchange,提问作者parapote

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 13:02:48