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

NavigationSplitView侧边栏列表选中项未高亮,如何结合SceneStorage实现高亮?

问题:NavigationSplitView侧边栏列表选中项无高亮效果

在NavigationSplitView的侧边栏中设置了列表,选中列表项时详情视图会随之切换,使用SceneStorage实现视图状态恢复,功能正常但存在以下问题:

  • 初始状态下"all"项未高亮
  • 状态恢复后选中项(如"frequently")也无高亮效果

原代码如下:

import SwiftUI

enum ListType: String {
   case all = "all"
   case frequently = "frequently"
}

struct MyListItem: Identifiable, Hashable {
   let type: ListType
   let label: String
   let id = UUID()
}

struct SelectionMode: View {
   
   @State private var listItems = [
      MyListItem(type: .all, label: "alle Unterrichte"),
      MyListItem(type: .frequently, label: "am häufigsten")
   ]

   @SceneStorage("ListType") private var selectedType: ListType?

   var body: some View {
    
      NavigationSplitView {
        List(listItems, id: \.self.type, selection: $selectedType) { type in
            NavigationLink("\(type.label)", value: type)
        }
      } detail: {
        NavigationStack {
            SelectedList(viewType: selectedType?.rawValue ?? "all")
        }
    }
}

解决方案

核心问题是List的selection绑定类型与NavigationLink的value类型不匹配,同时缺少初始选中状态设置,修改步骤如下:

1. 修正类型匹配与初始状态

将selectedType设置为非可选类型并指定初始值.all,让NavigationLink的value直接传递item.type,确保和selection绑定的ListType类型完全对齐。

2. 修改后的完整代码

import SwiftUI

enum ListType: String {
    case all = "all"
    case frequently = "frequently"
}

struct MyListItem: Identifiable, Hashable {
    let type: ListType
    let label: String
    let id = UUID()
}

struct SelectionMode: View {
    
    @State private var listItems = [
        MyListItem(type: .all, label: "alle Unterrichte"),
        MyListItem(type: .frequently, label: "am häufigsten")
    ]

    // 改为非可选类型,设置初始值为.all,通过SceneStorage持久化状态
    @SceneStorage("ListType") private var selectedType: ListType = .all

    var body: some View {
        
        NavigationSplitView {
            // List的selection与NavigationLink的value类型统一为ListType
            List(listItems, id: \.type, selection: $selectedType) { item in
                NavigationLink(item.label, value: item.type)
            }
        } detail: {
            NavigationStack {
                SelectedList(viewType: selectedType.rawValue)
            }
        }
    }
}

// 示例SelectedList实现
struct SelectedList: View {
    let viewType: String
    var body: some View {
        Text("当前视图类型:\(viewType)")
    }
}

关键修改说明

  • 去掉selectedType的可选标记?并设置初始值.all:确保App启动时默认选中"all"项并高亮,SceneStorage会自动保存后续选中状态,重启后恢复选中项并高亮。
  • 调整NavigationLink的value为item.type:让选中操作能正确同步到列表的高亮状态,解决类型不匹配导致的选中状态失效问题。

如果需要支持无选中状态,可保留selectedType的可选性并设置初始值:

@SceneStorage("ListType") private var selectedType: ListType? = .all

该写法同样能实现初始高亮与状态恢复后的高亮效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 16:21:02