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

SwiftUI AngularGradient环形渐变过渡生硬,如何实现平滑过渡效果?

优化方案

你当前实现渐变生硬核心有两个问题:

  1. AngularGradient固定配置为360度全范围渐变,但实际绘制时用trim只截取了部分环形,相当于只取了完整渐变的一个截断片段,自然没有平滑的过渡效果
  2. 渐变仅设置了红、绿两个极端色,中间没有过渡色阶,进度变化时色彩跳变感强

具体优化点

  • 动态匹配渐变角度和当前进度:把AngularGradient的endAngle改为和当前进度成正比的角度,而非固定360度,让渐变范围完全匹配你要绘制的环形长度
  • 补充过渡色值:在红、绿之间增加中间过渡色,让色彩变化更顺滑
  • 满环状态下做首尾衔接:如果需要进度100%时环形没有颜色断层,可在渐变首尾增加相同的颜色值做过渡

优化后代码

struct DiskSizeInfoView: View {
    // 总容量、已用容量可自行传入修改
    let total: Double = 1024
    let used: Double = 512
    // 计算进度和对应角度
    private var progress: Double { used / total }
    private var gradientEndAngle: Angle { .degrees(progress * 360) }
    
    var body: some View {
        ZStack {
            Circle()
                .stroke(Color(UIColor.secondarySystemBackground), lineWidth: 30)
            Circle()
                .trim(from: 0, to: progress)
                .stroke(
                    AngularGradient(
                        // 增加中间过渡色橙色,也可根据需求加更多色阶
                        gradient: Gradient(colors: [Color.red, Color.orange, Color.green]),
                        center: .center,
                        startAngle: .zero,
                        // 渐变结束角度和进度匹配
                        endAngle: gradientEndAngle
                    ),
                    style: StrokeStyle(lineWidth: 30, lineCap: .round, lineJoin: .round)
                )
                .rotationEffect(Angle(degrees: -90)) // 调整起始位置到顶部,无需额外3D翻转
            
            Text("\(Int(used))")
                .font(.system(size: 30, weight: .bold, design: .rounded))
        }
        .frame(width: 300, height: 300)
    }
}

额外说明

如果需要满环(progress=1)时首尾颜色平滑衔接,可把渐变调整为Gradient(colors: [Color.green, Color.red, Color.orange, Color.green]),这样首尾都是绿色,360度衔接不会有断层。
如果对渐变精度要求更高,还可以用Gradient(stops: [])自定义每个色值对应的角度位置,精准控制渐变过渡节奏。


内容的提问来源于stack exchange,提问作者Ufuk Köşker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 23:51:01