- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我使用 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/
我是一名优秀的程序员,十分优秀!