SwiftUI双窗格窗口:实现各窗格List的选中高亮问题
解决SwiftUI双窗格List选中高亮问题
要让双窗格中的两个List都实现选中高亮,无需依赖NavigationLink(避免无意义跳转),可以通过List的selection绑定结合tag来实现。以下是修改后的完整代码:
struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var items: [Item] // 分别管理左右两个List的选中项 @State private var leftSelectedItem: Item? @State private var rightSelectedItem: Item? var body: some View { NavigationSplitView { // 左侧List:保留跳转逻辑,同时通过selection绑定实现选中高亮 List(selection: $leftSelectedItem) { ForEach(items) { item in NavigationLink { Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))") } label: { Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard)) } .tag(item) // 为每行标记对应的Item,关联选中状态 } .onDelete(perform: deleteItems) } #if os(macOS) .navigationSplitViewColumnWidth(min: 180, ideal: 200) #endif .toolbar { #if os(iOS) ToolbarItem(placement: .navigationBarTrailing) { EditButton() } #endif ToolbarItem { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } detail: { // 右侧List:通过selection绑定实现选中高亮,无需跳转 List(selection: $rightSelectedItem) { ForEach(items) { item in Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))") .tag(item) // 标记每行对应的Item } .onDelete(perform: deleteItems) } } } // 补充原代码缺失的方法 private func addItem() { withAnimation { let newItem = Item(timestamp: Date()) modelContext.insert(newItem) } } private func deleteItems(offsets: IndexSet) { withAnimation { for index in offsets { modelContext.delete(items[index]) } } } }
关键修改说明
- 添加选中状态变量:用
@State定义leftSelectedItem和rightSelectedItem,分别绑定左右两个List的选中项。 - List绑定selection:给两个List都添加
selection: $xxxSelectedItem参数,开启选中管理功能。 - 为行添加tag:每个
ForEach中的行必须通过.tag(item)标记对应的Item实例,让List能识别选中的是哪一行。 - 右侧List无需NavigationLink:直接用
Text作为行内容,通过selection绑定就能实现选中高亮,完全不需要跳转逻辑。
这样修改后,左右两个List都能独立实现选中高亮效果,右侧List不再依赖无意义的NavigationLink。
内容的提问来源于stack exchange,提问作者Jon Buys
相关产品推荐
相关产品推荐

