macOS SwiftUI中ProgressView无法修改色调颜色的问题求助
macOS SwiftUI ProgressView 无法修改颜色的解决办法
在开发macOS SwiftUI应用的搜索功能时,需要在搜索执行时显示ProgressView,但尝试了.tint()、.foregroundStyle()、CircularProgressViewStyle(tint:)等方法都无法修改指示器颜色,始终显示默认的白/灰色。唯一可行的方式是设置.preferredColorScheme(.light),但这会改变整个应用的主题,体验很差。环境为macOS Ventura 13.5,构建目标macOS 12.4。
方案1:自定义圆形进度指示器样式
SwiftUI在macOS上的默认ProgressView样式对tint的支持有限,可以自行实现自定义ProgressViewStyle,完全控制颜色与动画:
struct CustomCircularProgressViewStyle: ProgressViewStyle { var tint: Color = .black func makeBody(configuration: Configuration) -> some View { Circle() .trim(from: 0, to: CGFloat(configuration.fractionCompleted ?? 0)) .stroke(tint, style: StrokeStyle(lineWidth: 2, lineCap: .round)) .rotationEffect(.degrees(-90)) .frame(width: 16, height: 16) .animation(.linear(duration: 1).repeatForever(autoreverses: false), value: configuration.fractionCompleted) } } // 使用示例 ProgressView(value: 0.5) .progressViewStyle(CustomCircularProgressViewStyle(tint: .black))
如果仅需要无限旋转的加载动画,无需精确进度值,可简化为:
struct InfiniteCircularProgressView: View { var tint: Color = .black var body: some View { Circle() .trim(from: 0.2, to: 1) .stroke(tint, style: StrokeStyle(lineWidth: 2, lineCap: .round)) .rotationEffect(.degrees(0)) .animation(.linear(duration: 1).repeatForever(autoreverses: false), value: UUID()) .frame(width: 16, height: 16) } }
方案2:用NSViewRepresentable包装NSProgressIndicator
直接使用AppKit的NSProgressIndicator组件,可完全控制其外观属性:
struct AppKitProgressView: NSViewRepresentable { var tint: Color = .black var isAnimating: Bool = true func makeNSView(context: Context) -> NSProgressIndicator { let indicator = NSProgressIndicator() indicator.style = .spinning indicator.controlSize = .small indicator.isDisplayedWhenStopped = false indicator.color = NSColor(tint) return indicator } func updateNSView(_ nsView: NSProgressIndicator, context: Context) { if isAnimating { nsView.startAnimation(nil) } else { nsView.stopAnimation(nil) } } } // 使用示例 AppKitProgressView(tint: .black)
修改你的SearchBar代码
将原代码中的ProgressView替换为自定义组件即可,比如使用AppKitProgressView:
// 替换原SearchBar中ProgressView的部分 if isSearching { AppKitProgressView(tint: .black) .scaleEffect(0.75) }
额外说明
macOS上的SwiftUI ProgressView底层依赖NSProgressIndicator,系统默认样式会受系统外观(深色/浅色模式)的强约束,导致tint设置失效。自定义样式或直接使用AppKit组件可绕过这一限制,实现完全的颜色控制。
内容的提问来源于stack exchange,提问作者Matias Carulli
相关产品推荐
相关产品推荐

