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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:25:27