如何防止弹出确认对话框时可选择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("确定要删除这些项吗?") } ) } } } } }
关键说明
- 手动控制编辑模式:通过
isEditing变量和environment(\.editMode)绑定,完全接管编辑状态的切换逻辑,避免系统在弹出对话框时自动退出编辑模式,从而防止选中状态被清空。 - 暂存选中状态:在触发对话框前将
selection的值存入tempSelection,确保对话框中的删除操作基于弹出前的选中项执行,删除完成后再同步更新selection,保持界面状态一致性。
内容的提问来源于stack exchange,提问作者parapote
相关产品推荐
相关产品推荐

