NavigationSplitView侧边栏列表选中项未高亮,如何结合SceneStorage实现高亮?
在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
相关产品推荐
相关产品推荐

