如何取消SwiftUI中NavigationSplitView侧边栏的颜色淡化效果
问题
iOS16的NavigationSplitView使用.automatic或.prominentDetail样式时,深色模式下列表内设置了自定义颜色的系统图标会被淡化,亮色模式显示正常,需取消该淡化效果。
示例代码
import SwiftUI struct ContentView: View { var body: some View { NavigationSplitView { List { ForEach([1, 2, 3], id: \.self) { item in Button { } label: { HStack { Image(systemName: "sunset.circle.fill") .foregroundColor(.green) Text("Item \(item)") } .font(.system(size: 40)) .padding() } } } } detail: { Text("Detailed Content") } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { Group { ContentView() .previewInterfaceOrientation(.portrait) .preferredColorScheme(.dark) ContentView() .previewInterfaceOrientation(.portrait) .preferredColorScheme(.light) } } }
效果对比
- 深色模式(颜色淡化):

- 亮色模式(颜色正常):

解决方法
1. 调整Button样式
系统对NavigationSplitView侧边栏内的Button默认应用了淡化效果,将Button样式改为.plain即可避免:
Button { } label: { // 原label内容 } .buttonStyle(.plain)
如果仍有淡化,给Image添加colorMultiply强化颜色:
Image(systemName: "sunset.circle.fill") .foregroundColor(.green) .colorMultiply(.green)
2. 用手势替代Button
直接使用onTapGesture替代Button,彻底摆脱系统对Button的样式干预:
List { ForEach([1, 2, 3], id: \.self) { item in HStack { Image(systemName: "sunset.circle.fill") .foregroundColor(.green) Text("Item \(item)") } .font(.system(size: 40)) .padding() .onTapGesture { // 点击事件逻辑 } } }
3. UIKit层面修改
通过扩展UINavigationController,禁用侧边栏列表的颜色调整模式:
import UIKit extension UINavigationController { override open func viewDidLoad() { super.viewDidLoad() guard let splitVC = splitViewController as? UISplitViewController, let sidebarNav = splitVC.viewControllers.first as? UINavigationController, let tableView = sidebarNav.topViewController?.view.subviews.first(where: { $0 is UITableView }) as? UITableView else { return } tableView.tintAdjustmentMode = .normal } }
将此代码加入项目,系统就不会再淡化侧边栏内的图标颜色。
内容的提问来源于stack exchange,提问作者stanlemon
相关产品推荐
相关产品推荐

