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

SwiftUI中如何在Trim填充值末端添加小圆圈

实现环形进度条末端的小圆圈标记

要在trim填充的环形末端添加小圆圈,核心思路是根据fillValue计算出环形末端的角度位置,再将小圆圈精准定位到该位置即可。以下是具体实现方案:

核心实现逻辑

  1. 角度计算:fillValue对应环形的填充比例,乘以360°即可得到填充部分对应的角度。
  2. 位置定位:基于环形的中心线半径,将小圆圈偏移到环形边缘,再通过旋转对齐到填充末端的角度。
  3. 旋转同步:原环形通过rotationEffect(.degrees(90))将起始点移到右侧,小圆圈需要同步该旋转,确保位置完全对应。

修改后的完整代码

struct CountdownView: View {
  
  @State var fillValue: CGFloat = 0.7
  private let lineWidth: CGFloat = 6

  var body: some View {
      ZStack {
            // 背景白色圆环
            Circle()
                .foregroundColor(.white)
                .shadow(radius: 0.5)
            
            // 进度环形
            Circle()
                .trim(from: 0, to: fillValue)
                .stroke(Color.blue, style: .init(lineWidth: lineWidth))
                .rotationEffect(.degrees(90))
            
            // 末端小圆圈标记
            GeometryReader { geo in
                // 计算环形中心线半径(减去线宽一半,因为stroke是居中绘制)
                let centerRadius = (geo.size.width / 2) - (lineWidth / 2)
                Circle()
                    .fill(Color.blue)
                    // 小圆圈尺寸比线宽大2,确保覆盖环形末端
                    .frame(width: lineWidth + 2, height: lineWidth + 2)
                    // 偏移到环形边缘位置
                    .offset(x: 0, y: -centerRadius)
                    // 根据fillValue旋转到对应角度
                    .rotationEffect(.degrees(fillValue * 360))
                    // 和进度环形保持相同初始旋转
                    .rotationEffect(.degrees(90))
            }
        }
        .frame(width: 250, height: 250)
        .padding()
  }
}

关键细节说明

  • 用GeometryReader动态获取视图尺寸,调整frame大小或线宽时,小圆圈位置会自动适配,无需手动修改偏移值。
  • 小圆圈尺寸设为lineWidth + 2,既能覆盖环形末端,又不会显得突兀。
  • 两次rotationEffect组合:第一次根据fillValue计算旋转角度,第二次同步进度环形的初始旋转,保证fillValue为0时小圆圈和环形起始点完全对齐。

内容的提问来源于stack exchange,提问作者Taimoor Arif

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:33:37