iOS 16下SwiftUI List多选功能失效问题问询
iOS 16/Xcode 14 中 List 多选退出编辑后选中状态被清空的问题
环境
- iOS 16
- Xcode 14.0
问题重现代码
struct ContentView: View { struct Ocean: Identifiable, Hashable { let name: String let id = UUID() } private var oceans = [ Ocean(name: "Pacific"), Ocean(name: "Atlantic"), Ocean(name: "Indian"), Ocean(name: "Southern"), Ocean(name: "Arctic") ] @State private var multiSelection = Set<UUID>() var body: some View { NavigationView { List(oceans, selection: $multiSelection) { Text($0.name) } .navigationTitle("Oceans") .toolbar { EditButton() } } Text("\(multiSelection.count) selections") } }
问题说明
在 Xcode 13 中,点击Edit按钮选择列表项,按下Done后底部仍能正常显示选中数量;但升级到 Xcode 14/iOS 16 后,点击Done时multiSelection会被直接重置为空,导致底部计数归零。提交 Bug 报告后 Apple 回复此为预期行为,核心是对系统默认多选场景的理解偏差。
解决方案
系统默认的EditButton设计逻辑是配合临时批量操作(比如删除、移动),退出编辑时自动清空选中状态。如果需要持久化选中状态,需手动管理编辑模式:
方案一:手动控制编辑模式,保留选中集合
通过自定义按钮切换编辑状态,直接控制editMode环境变量,避免系统自动清空选中集合:
struct ContentView: View { struct Ocean: Identifiable, Hashable { let name: String let id = UUID() } private var oceans = [ Ocean(name: "Pacific"), Ocean(name: "Atlantic"), Ocean(name: "Indian"), Ocean(name: "Southern"), Ocean(name: "Arctic") ] @State private var multiSelection = Set<UUID>() @State private var isEditing = false var body: some View { NavigationView { List(oceans, selection: $multiSelection) { Text($0.name) } .navigationTitle("Oceans") .toolbar { Button(isEditing ? "Done" : "Edit") { withAnimation { isEditing.toggle() } } } .environment(\.editMode, .constant(isEditing ? .active : .inactive)) } Text("\(multiSelection.count) selections") } }
方案二:保存选中状态到独立变量
如果需要区分「编辑时临时选中」和「最终确认选中」,可以在退出编辑时把选中集合保存到单独的状态变量:
struct ContentView: View { struct Ocean: Identifiable, Hashable { let name: String let id = UUID() } private var oceans = [ Ocean(name: "Pacific"), Ocean(name: "Atlantic"), Ocean(name: "Indian"), Ocean(name: "Southern"), Ocean(name: "Arctic") ] @State private var multiSelection = Set<UUID>() @State private var savedSelection = Set<UUID>() @State private var isEditing = false var body: some View { NavigationView { List(oceans, selection: $multiSelection) { Text($0.name) } .navigationTitle("Oceans") .toolbar { Button(isEditing ? "Done" : "Edit") { withAnimation { if isEditing { savedSelection = multiSelection } isEditing.toggle() } } } .environment(\.editMode, .constant(isEditing ? .active : .inactive)) } Text("\(savedSelection.count) selections") } }
补充说明
Apple 的设计逻辑是:系统默认的EditButton+List 多选,仅用于一次性批量操作,操作完成后退出编辑,选中状态自然清空。如果需要持久化选中,就需要脱离系统默认的自动管理逻辑,手动控制编辑状态和选中集合。
内容的提问来源于stack exchange,提问作者Skk
相关产品推荐
相关产品推荐

