SwiftUI如何为圆形进度条的端点添加自定义图标?
你可以通过三角函数计算进度条端点的坐标,再将图标叠加到对应位置实现需求,实现逻辑和代码如下:
实现原理
圆形进度条的起点默认在右侧,你已经通过旋转90度将起点调整到顶部,进度端点的角度可以通过进度占比 * 360度 - 90度计算得到,再通过三角函数即可算出端点的x、y坐标,最后将图标定位到该坐标即可。
完整实现代码
import SwiftUI struct ProgressCircleWithIcon: View { /// 进度值,取值范围0~1 let progress: Double /// 进度条线宽 let lineWidth: Double /// 圆形进度条整体尺寸 let circleSize: Double /// 进度条颜色 let progressColor: Color /// 端点图标 let endIcon: Image var body: some View { ZStack { // 原有基础进度条实现 Circle() .trim(from: 0, to: progress) .stroke(style: StrokeStyle(lineWidth: lineWidth, lineCap: .round, lineJoin: .round)) .rotationEffect(.degrees(-90)) .foregroundColor(progressColor) // 放置端点图标 endIcon .resizable() .scaledToFit() .frame(width: lineWidth * 1.2, height: lineWidth * 1.2) .foregroundColor(.white) .position(calculateEndPoint()) } .frame(width: circleSize, height: circleSize) .padding() } /// 计算进度条末端的坐标 private func calculateEndPoint() -> CGPoint { let center = CGPoint(x: circleSize / 2, y: circleSize / 2) // 实际半径要减去线宽,避免图标超出进度条范围 let radius = (circleSize - lineWidth) / 2 // 角度转弧度,从顶部开始计算 let radian = 2 * Double.pi * progress - Double.pi / 2 let x = center.x + radius * cos(radian) let y = center.y + radius * sin(radian) return CGPoint(x: x, y: y) } } // 使用示例 struct ContentView: View { var body: some View { ProgressCircleWithIcon( progress: 0.6, lineWidth: 24, circleSize: 300, progressColor: .green, endIcon: Image(systemName: "checkmark.circle.fill") ) } }
调整说明
- 你可以自行修改图标大小的计算规则,比如改成固定数值,适配你的设计需求
- 如果需要同时给起点也添加图标,额外计算
radian = -Double.pi / 2对应的坐标,再添加一个图标视图即可 - 如果图标需要显示其他颜色或样式,直接修改
endIcon的修饰符即可
内容的提问来源于stack exchange,提问作者TruMan1
相关产品推荐
相关产品推荐

