通过使用以下 SwiftUI 代码,当应用程序在带有 M1 的 XCode(模拟器)中运行时,我的应用程序造成的 CPU 消耗高达 55%。
在真正的 iPhone 上,CPU 高达 52%
仅供参考:circleProgess 正在更新每 0.1 秒。
Circle()
.trim(from: 0.0, to: circleProgress)
.stroke(style: StrokeStyle(lineWidth: 10, lineCap: .round, lineJoin: .round))
.fill(Color.pink.gradient)
.rotationEffect(Angle(degrees: 270.0))
.animation(.default, value: circleProgress)
.frame(width: 100, height: 100)
我发现CPU高不仅是由Color.pink.gradient线引起的。
如果我使用相同的代码,但使用 Color.pink 而不是 Color.pink。gradient,XCode 模拟器上的 CPU 使用率约为 15% 。在真实设备上,例如iPhone 12 CPU依然高达35%
这是一个可重现的示例
struct ContentView: View {
@ObservedObject var someTimer = SomeTimer()
var body: some View {
AnimatedCircle(circleProgress: $someTimer.circleProgess, size: 100)
AnimatedCircle(circleProgress: $someTimer.circleProgess, size: 400)
Spacer()
Button(action: someTimer.start, label: {
Text("Start animation")
})
Spacer()
}
}
class SomeTimer : ObservableObject {
@Published var circleProgess = 1.0
func start() {
circleProgess = 1.0
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) {_ in
self.circleProgess -= 0.001
}
}
}
struct AnimatedCircle: View {
@Binding var circleProgress : Double
var size : Int
var body: some View {
Circle()
.trim(from: 0.0, to: CGFloat(circleProgress))
.stroke(style: StrokeStyle(lineWidth: 20, lineCap: .round, lineJoin: .round))
.fill(Color.pink.gradient)
//.fill(Color.pink)
.rotationEffect(Angle(degrees: 270.0))
.animation(.default, value: CGFloat(circleProgress))
.frame(width: CGFloat(size), height: CGFloat(size))
}
}
运行 AnimatedCircle() 会产生巨大的 CPU 消耗差异 .fill(Color.pink.gradient) 或使用 .fill(Color.pink)
有什么想法可以让我将这个动画与 Color.pink 一起使用。gradient 并且仍然保持 CPU 使用率远低于 55%?
谢谢
使用您的
Timer
示例,我发现该应用程序在运行 iOS 17.5 的 iPhone 15 模拟器上运行时使用了大约 47% 的 CPU。
如果先填充圆圈,然后将修剪后的形状应用为蒙版,则使用的 CPU 会更少:
Circle()
.fill(Color.pink.gradient)
.frame(width: CGFloat(size), height: CGFloat(size))
.mask {
Circle()
.inset(by: 10) // half the line width
.trim(from: 0.0, to: CGFloat(circleProgress))
.stroke(style: StrokeStyle(lineWidth: 20, lineCap: .round, lineJoin: .round))
.rotationEffect(Angle(degrees: 270.0))
.animation(.default, value: CGFloat(circleProgress))
}
在我的测试中,这仅在模拟器中使用了大约 8% 的 CPU。