SwiftUI NavigationSplitView iPad侧栏:移除选中项的高亮矩形
我正在开发适配iPad和iPhone的应用,使用NavigationSplitView组件,希望仅通过“Selected”文字标记侧栏选中项。但在iPad Air 5代模拟器中,选中项会显示蓝色高亮矩形,而预览中无此矩形(符合预期)。移除.listRowBackground()后,预览中变为浅灰色高亮,模拟器仍为蓝色。尝试以下方法均未解决:
- 将
.listRowBackground(EmptyView())替换为.listRowBackground(Color.clear) - 使用已弃用的
.accentColor(.clear)(矩形变为白色) - 添加
.tint(.clear)和.listItemTint(.clear) - 用ForEach替代List(需重构布局且效果不一致)
需要保留黄色背景,求移除该高亮矩形的方法。
原代码
struct MyView: View { @State private var selected: MyContent? let list = [MyContent("First"), MyContent("Second"), MyContent("Third")] var body: some View { NavigationSplitView { List(list, selection: $selected) { item in NavigationLink(value: item) { HStack { Text(item.title) Spacer() Text(selected == item ? "Selected" : "") } .foregroundColor(.primary) } .listRowBackground(EmptyView()) } .scrollContentBackground(.hidden) .listStyle(.plain) .background(.yellow) } detail: { if let selected { Text("Detail of \(selected.title)") } } } } struct MyContent: Identifiable, Hashable { let id = UUID() let title: String init(_ title: String) { self.title = title } }
效果对比
预期效果(预览中正常)

需移除的蓝色矩形(模拟器中显示)

部署环境:iOS 16.0,Xcode 14
解决方案
方法一:移除List的selection绑定,改用自定义Button
彻底脱离系统的选中样式管理,用Button手动控制选中状态和详情更新,完全避免高亮矩形出现:
struct MyView: View { @State private var selected: MyContent? let list = [MyContent("First"), MyContent("Second"), MyContent("Third")] var body: some View { NavigationSplitView { List(list) { item in Button { selected = item } label: { HStack { Text(item.title) Spacer() Text(selected == item ? "Selected" : "") } .foregroundColor(.primary) } .listRowBackground(Color.clear) } .scrollContentBackground(.hidden) .listStyle(.plain) .background(.yellow) } detail: { if let selected { Text("Detail of \(selected.title)") } } } } struct MyContent: Identifiable, Hashable { let id = UUID() let title: String init(_ title: String) { self.title = title } }
方法二:保留List的selection绑定,禁用系统选中样式
如果需要保留List的selection绑定逻辑,给List添加environment(\.selectionStyle, .none)即可禁用系统自带的高亮矩形:
struct MyView: View { @State private var selected: MyContent? let list = [MyContent("First"), MyContent("Second"), MyContent("Third")] var body: some View { NavigationSplitView { List(list, selection: $selected) { item in NavigationLink(value: item) { HStack { Text(item.title) Spacer() Text(selected == item ? "Selected" : "") } .foregroundColor(.primary) } .listRowBackground(Color.clear) } .scrollContentBackground(.hidden) .listStyle(.plain) .background(.yellow) .environment(\.selectionStyle, .none) // 添加此行禁用选中高亮 } detail: { if let selected { Text("Detail of \(selected.title)") } } } } struct MyContent: Identifiable, Hashable { let id = UUID() let title: String init(_ title: String) { self.title = title } }
内容的提问来源于stack exchange,提问作者HunterLion
相关产品推荐
相关产品推荐

