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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:05:30