SwiftUI:如何创建带有 "fade out" 起始行的圆形 "progress" 条形小部件(如果它已满(100%)),例如 iOS 上的 "battery" 小部件
SwiftUI: How to create circular "progress" bar widget with a "fade out" start line if it is full (100%), like the "battery" widget on iOS
我正在 SwiftUI 中创建自己的“圆形”进度条小部件,我想知道如何实现他所遵循的。如果圆圈进度为 100%(表示圆圈已满),我希望线的“开始”具有“淡出”效果,以便线的开始和结束不会“合并”。我在 iOS 上的“电池”小部件中看到了这一点。这是“充满”和“未充满”电池小部件的示例:
这是我当前的小部件代码:
struct CircleProgressView: View {
@Binding var progress: Float
var body: some View {
ZStack {
Circle()
.stroke(lineWidth: 10)
.opacity(0.3)
.foregroundColor(Color(UIColor.systemGray3))
Circle()
.trim(from: 0.0, to: CGFloat(min(self.progress, 1.0)))
.stroke(style: StrokeStyle(lineWidth: 10, lineCap: .round, lineJoin: .round))
.foregroundColor(Color(UIColor.systemGreen))
.rotationEffect(Angle(degrees: 270.0))
}
.padding()
}
}
任何想法都会有所帮助。
这是一个方法。
我叠了 4 个圆圈:
- 灰色底座
- 接收阴影的第一个绿色圆圈
- 用阴影+clipshape 将一个圆圈剪裁成一个点,以消除圆圈两侧的阴影
- 另一个绿色圆圈遮住一侧的阴影
代码如下:
struct CircleProgressView: View {
@Binding var progress: Float
var body: some View {
ZStack {
// grey background circle
Circle()
.stroke(lineWidth: 30)
.opacity(0.3)
.foregroundColor(Color(UIColor.systemGray3))
// green base circle to receive shadow
Circle()
.trim(from: 0.0, to: CGFloat(min(self.progress, 0.5)))
.stroke(style: StrokeStyle(lineWidth: 30, lineCap: .round, lineJoin: .round))
.foregroundColor(Color(UIColor.systemGreen))
.rotationEffect(Angle(degrees: 270.0))
// point with shadow, clipped
Circle()
.trim(from: CGFloat(abs((min(progress, 1.0))-0.001)), to: CGFloat(abs((min(progress, 1.0))-0.0005)))
.stroke(style: StrokeStyle(lineWidth: 30, lineCap: .round, lineJoin: .round))
.foregroundColor(Color(UIColor.blue))
.shadow(color: .black, radius: 10, x: 0, y: 0)
.rotationEffect(Angle(degrees: 270.0))
.clipShape(
Circle().stroke(lineWidth: 30)
)
// green overlay circle to hide shadow on one side
Circle()
.trim(from: progress > 0.5 ? 0.25 : 0, to: CGFloat(min(self.progress, 1.0)))
.stroke(style: StrokeStyle(lineWidth: 30, lineCap: .round, lineJoin: .round))
.foregroundColor(Color(UIColor.systemGreen))
.rotationEffect(Angle(degrees: 270.0))
}
.padding()
}
}
我正在 SwiftUI 中创建自己的“圆形”进度条小部件,我想知道如何实现他所遵循的。如果圆圈进度为 100%(表示圆圈已满),我希望线的“开始”具有“淡出”效果,以便线的开始和结束不会“合并”。我在 iOS 上的“电池”小部件中看到了这一点。这是“充满”和“未充满”电池小部件的示例:
这是我当前的小部件代码:
struct CircleProgressView: View {
@Binding var progress: Float
var body: some View {
ZStack {
Circle()
.stroke(lineWidth: 10)
.opacity(0.3)
.foregroundColor(Color(UIColor.systemGray3))
Circle()
.trim(from: 0.0, to: CGFloat(min(self.progress, 1.0)))
.stroke(style: StrokeStyle(lineWidth: 10, lineCap: .round, lineJoin: .round))
.foregroundColor(Color(UIColor.systemGreen))
.rotationEffect(Angle(degrees: 270.0))
}
.padding()
}
}
任何想法都会有所帮助。
这是一个方法。 我叠了 4 个圆圈:
- 灰色底座
- 接收阴影的第一个绿色圆圈
- 用阴影+clipshape 将一个圆圈剪裁成一个点,以消除圆圈两侧的阴影
- 另一个绿色圆圈遮住一侧的阴影
代码如下:
struct CircleProgressView: View {
@Binding var progress: Float
var body: some View {
ZStack {
// grey background circle
Circle()
.stroke(lineWidth: 30)
.opacity(0.3)
.foregroundColor(Color(UIColor.systemGray3))
// green base circle to receive shadow
Circle()
.trim(from: 0.0, to: CGFloat(min(self.progress, 0.5)))
.stroke(style: StrokeStyle(lineWidth: 30, lineCap: .round, lineJoin: .round))
.foregroundColor(Color(UIColor.systemGreen))
.rotationEffect(Angle(degrees: 270.0))
// point with shadow, clipped
Circle()
.trim(from: CGFloat(abs((min(progress, 1.0))-0.001)), to: CGFloat(abs((min(progress, 1.0))-0.0005)))
.stroke(style: StrokeStyle(lineWidth: 30, lineCap: .round, lineJoin: .round))
.foregroundColor(Color(UIColor.blue))
.shadow(color: .black, radius: 10, x: 0, y: 0)
.rotationEffect(Angle(degrees: 270.0))
.clipShape(
Circle().stroke(lineWidth: 30)
)
// green overlay circle to hide shadow on one side
Circle()
.trim(from: progress > 0.5 ? 0.25 : 0, to: CGFloat(min(self.progress, 1.0)))
.stroke(style: StrokeStyle(lineWidth: 30, lineCap: .round, lineJoin: .round))
.foregroundColor(Color(UIColor.systemGreen))
.rotationEffect(Angle(degrees: 270.0))
}
.padding()
}
}