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

SwiftUI中带UUID的双列表选中状态互斥问题求助

问题原因与解决方案

问题出在每次ContentView的body刷新时,两个List里的ListItem数组都会被重新创建,每个新的ListItem都会生成全新的UUID。当你选中第二个列表的项触发body刷新后,第一个列表原来的选中UUID已经不存在于新生成的数组里了,系统会自动清空第一个列表的选中状态。而使用字符串数组时,id: \.self对应的是字符串本身,不管数组怎么重建,字符串内容不变,选中的id始终存在,所以状态能正常保留。

解决方案1:将ListItem数组设为静态常量

把数组提取为静态常量,确保UUID只生成一次,不会随body刷新重新创建:

struct ListItem: Identifiable {
    let id = UUID()
    let name: String
}

// 静态常量,仅初始化一次
private let listItems = [ListItem(name: "Item 1"), ListItem(name: "Item 2"), ListItem(name: "Item 3")]

struct ContentView: View {
    @State var sel1: UUID?
    @State var sel2: UUID?
    
    var body: some View {
        HStack {
            List(listItems, selection: $sel1) { item in
                Text(item.name)
            }
            List(listItems, selection: $sel2) { item in
                Text(item.name)
            }
        }
    }
}

解决方案2:让ListItem的id基于唯一标识(如name)

如果列表项的name是唯一的,可以直接用name作为id,这样即使数组重建,id也不会改变:

struct ListItem: Identifiable {
    var id: String { name } // 用name作为唯一标识
    let name: String
}

struct ContentView: View {
    @State var sel1: String?
    @State var sel2: String?
    
    var body: some View {
        HStack {
            List([ListItem(name: "Item 1"), ListItem(name: "Item 2"), ListItem(name: "Item 3")], selection: $sel1) { item in
                Text(item.name)
            }
            List([ListItem(name: "Item 1"), ListItem(name: "Item 2"), ListItem(name: "Item 3")], selection: $sel2) { item in
                Text(item.name)
            }
        }
    }
}

解决方案3:用@State保存数组

将数组存储在@State属性中,避免每次body刷新时重新生成ListItem实例:

struct ListItem: Identifiable {
    let id = UUID()
    let name: String
}

struct ContentView: View {
    @State var sel1: UUID?
    @State var sel2: UUID?
    @State private var listItems = [ListItem(name: "Item 1"), ListItem(name: "Item 2"), ListItem(name: "Item 3")]
    
    var body: some View {
        HStack {
            List(listItems, selection: $sel1) { item in
                Text(item.name)
            }
            List(listItems, selection: $sel2) { item in
                Text(item.name)
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:03:24