gpt4 book ai didi

ios - Swift 中自定义属性的隐式 CALayer 动画

转载 作者:搜寻专家 更新时间:2023-10-31 21:48:13 26 4
gpt4 key购买 nike

我使用 PaintCode 创建了一个可动画化的 Core Graphics 绘图。它基本上是一个圆表(与 Apple Watch 环不同),它基本上会随着计时器倒计时而填满。 meterLevel 控制圆形仪表的填充级别,从 0 到 100。基本上,如果定时器设置为 10 秒,我将每 1 秒的 meterLevel 设置为 90、80、70 等...

效果不错,但是动画每 1 秒才绘制一次,而且看起来很不稳定。相反,我希望它是一个平滑的连续填充计。

环顾四周,似乎子类化 CALayer 并为 meterLevel 属性创建隐式动画可能是可行的方法。所以这就是我所拥有的:

import UIKit

class MeterControlView: UIView
{
var meterLevel: Int = 0 {
didSet {
self.layer.setValue(meterLevel, forKey: "meterLevel")
}
}
var meterText: String = "00:00:00" {
didSet {
self.layer.setValue(meterText, forKey: "meterText")
}
}


override class func layerClass() -> AnyClass {
return MeterControlLayer.self
}

override func drawRect(rect: CGRect) {
// Do nothing
}
}

class MeterControlLayer: CALayer
{
@NSManaged
var meterLevel: Int
var meterText: String = "00:00:00"

override class func needsDisplayForKey(key: String) -> Bool {
if (key == "meterLevel") {
return true
}
return super.needsDisplayForKey(key)
}

override func actionForKey(key: String) -> CAAction? {
if (key == "meterLevel") {
let anim: CABasicAnimation = CABasicAnimation.init(keyPath: key)
anim.fromValue = self.presentationLayer()?.meterLevel
anim.duration = 1.0
return anim
} else {
return super.actionForKey(key)
}
}

override func drawInContext(ctx: CGContext) {
super.drawInContext(ctx)
UIGraphicsPushContext(ctx)
XntervalStyleKit.drawMeterControl(frame: self.bounds, meterTime: meterText, meterLevelValue: CGFloat(meterLevel))
UIGraphicsPopContext()
}
}

不幸的是,这并不完全符合我的预期。动画仍然有点断断续续,但更接近我想要的。

但我的问题更笼统,这是完成我想做的事情的正确方法吗?在不使用 setValueForKey: 的情况下,我想不出设置图层属性 meterLevel 和 meterText 的正确方法。这是执行此操作的正确方法吗?

动画/图形对我来说绝对是新事物。我是一名嵌入式 C 软件专家,正试图将 iOS 开发作为一种爱好。

最佳答案

The animation is still a bit choppy, though closer to what I want.

鉴于此,似乎 Core Animation 实际上在每一帧绘制您的层(或无论如何尝试)。

不幸的是,一旦你在每一帧执行自定义图层绘制,你的性能就变成了主线程绑定(bind):也就是说,通常,对于 Core Animation 可以原生动画的属性(例如边界),动画本身在渲染服务器中渲染,它在您的应用程序的进程外运行,并有自己的高优先级渲染线程。在这些类型的动画期间,您的应用程序的主线程可以自由地做任何它想做的事情,而不会中断动画。

但是,

drawInContext(_:) 是在应用程序的主线程上调用的。如果你在那里放置一个日志语句或断点,它是否在你的动画持续过程中被调用了很多次?如果是这样,则该层正在正确设置动画。您在此函数中的绘图操作可能会阻碍动画。

尝试在图层上将 drawsAsynchronously 设置为 true。这将绘图命令推迟到后台线程,有时可以提高性能。 (请注意,大多数(如果不是全部的话)UIGraphics 和 Core Graphics 函数在 iOS 4 中都是线程安全的,因此背景绘制是安全的。)

此外,根据动画的复杂程度,您可能需要提前绘制多个中间表示(如果可能,在背景中并行绘制)。如果它们不太大,请将它们存储在内存中的某个位置,这样您就可以简单地在图层中显示其中的一些位图,而不是即时绘制它们。

关于ios - Swift 中自定义属性的隐式 CALayer 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33396905/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com