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
相关产品推荐
相关产品推荐

