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

SwiftUI List手动设置选中状态及增删项异常问题

解决macOS SwiftUI列表删除后详情视图不消失及新增项选中问题

问题说明

  • 删除选中的列表项后,详情视图仍显示已删除项的内容,无法回到默认提示文本
  • 点击ADD按钮新增列表项后,选中状态停留在原最后一项,无法自动切换到新创建的项

解决方案

1. 关联NavigationLink与selection状态

原代码中NavigationLink未与selection绑定,导致selection变化无法同步控制详情视图的显示。需修改为tag-selection绑定的形式,让selection直接控制导航状态:

NavigationLink(destination: DetailView(item: item), tag: item, selection: $selection) {
    Text(item)
}

2. 删除时清空选中状态

在删除操作后,检查被删除的项是否为当前选中项,若是则将selection设为nil,触发详情视图关闭:

  • 修改批量删除方法:
func delete(at offsets: IndexSet) {
    let deletedItems = offsets.map { items[$0] }
    items.remove(atOffsets: offsets)
    // 若删除的是当前选中项,清空选中状态
    if deletedItems.contains(selection) {
        selection = nil
    }
}
  • 修复单个删除方法:
func delete(item: String) {
    if let index = items.firstIndex(of: item) {
        items.remove(at: index)
        // 若删除的是当前选中项,清空选中状态
        if selection == item {
            selection = nil
        }
    }
}

3. 新增项自动选中

完善add()方法确保返回正确的新项,同时因为NavigationLink已与selection绑定,设置selection = newCreatedItem即可自动选中并导航到新项详情:

func add() -> String {
    let newItem = "Item \(items.count + 1)"
    items.append(newItem)
    return newItem
}

修改后的完整代码

struct DetailView: View {
    var item: String
    var body: some View {
        Text("Detail of \(item)")
    }
}

struct ContentView: View {
    @State private var items = ["Item 1", "Item 2", "Item 3"]
    @State private var selection: String?
    
    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(items, id: \.self, selection: $selection) { item in
                        // 修改NavigationLink为tag-selection绑定形式
                        NavigationLink(destination: DetailView(item: item), tag: item, selection: $selection) {
                            Text(item)
                        }
                    }
                    .onDelete(perform: delete)
                }
                
                Button {
                    let newCreatedItem = add()
                    selection = newCreatedItem // 现在可以正常触发选中和导航
                } label: {
                    Image(systemName: "add")
                }
                
                Button {
                    if let item = selection {
                        delete(item: item)
                    }
                } label: {
                    Image(systemName: "minus.rectangle.fill")
                }
                .disabled(selection == nil)
            }
            Text("Please select an item.")
        }
    }
    
    func delete(at offsets: IndexSet) {
        let deletedItems = offsets.map { items[$0] }
        items.remove(atOffsets: offsets)
        if deletedItems.contains(selection) {
            selection = nil
        }
    }
    
    func delete(item: String) {
        if let index = items.firstIndex(of: item) {
            items.remove(at: index)
            if selection == item {
                selection = nil
            }
        }
    }
    
    func add() -> String {
        let newItem = "Item \(items.count + 1)"
        items.append(newItem)
        return newItem
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:00:56