代码之家  ›  专栏  ›  技术社区  ›  LetsBeHappy

高CPU的圆形渐变动画

  •  0
  • LetsBeHappy  · 技术社区  · 11 月前

    通过使用以下SwiftUI代码,我的应用程序造成的CPU消耗为 高达55% 当应用程序在带有M1的XCode(模拟器)中运行时。

    在真正的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引起的,而且主要是由它引起的。 坡度 线

    如果我使用相同的代码,但使用Color.pink而不是Color.pink。 坡度 CPU使用率约为15% 在XCode模拟器上。在真实设备上,例如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(颜色、粉红色、渐变)或带有.fill(色彩、粉红色)

    任何想法我可以如何使用这个动画与Color.pink。 坡度 并且仍然保持CPU使用率远低于55%?
    谢谢

    1 回复  |  直到 11 月前
        1
  •  0
  •   Benzy Neez    11 月前

    使用您的 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。

        2
  •  0
  •   LetsBeHappy    11 月前

    此图显示了连接到M1 mac上运行的XCode并使用Benzy Neez方法的iPhone12的CPU使用情况。圆圈画得越长,CPU使用率就越高

    CPU usage for an iPhone12