Ios 在计算过程中修改值
假设你有一个简单的动画Ios 在计算过程中修改值,ios,swift,caanimation,Ios,Swift,Caanimation,假设你有一个简单的动画 let e : CABasicAnimation = CABasicAnimation(keyPath: "strokeEnd") e.duration = 2.0 e.fromValue = 0 e.toValue = 1.0 e.repeatCount = .greatestFiniteMagnitude self.someLayer.add(e, forKey: nil) 一层的 private lazy var
let e : CABasicAnimation = CABasicAnimation(keyPath: "strokeEnd")
e.duration = 2.0
e.fromValue = 0
e.toValue = 1.0
e.repeatCount = .greatestFiniteMagnitude
self.someLayer.add(e, forKey: nil)
一层的
private lazy var someLayer: CAShapeLayer
读取每个动画步骤的strokeEnd值非常容易
只需更改为自定义图层
private lazy var someLayer: CrazyLayer
然后
class CrazyLayer: CAShapeLayer {
override func draw(in ctx: CGContext) {
print("Yo \(presentation()!.strokeEnd)")
super.draw(in: ctx)
}
}
实际上,在每一步都可以设置图层的特性值,这将非常方便
例如:
class CrazyLayer: CAShapeLayer {
override func draw(in ctx: CGContext) {
print("Yo \(presentation()!.strokeEnd)")
strokeStart = presentation()!.strokeEnd - 0.3
super.draw(in: ctx)
}
}
当然你不能那样做-
正在尝试修改只读层
也许您可以有一个自定义的可设置动画的属性
class LoopyLayer: CAShapeLayer {
@NSManaged var trick: CGFloat
override class func needsDisplay(forKey key: String) -> Bool {
if key == "trick" { return true }
return super.needsDisplay(forKey: key)
}
... somehow for each frame
strokeEnd = trick * something
backgroundColor = alpha: trick
}
如何“手动”设置每个帧的可设置动画的属性值
是否有一种方法可以简单地提供(覆盖?)一个计算每帧值的函数?如何通过计算其他特性或其他自定义特性,在某些特性上设置每个帧的值
(脚注1-一个棘手的解决办法是滥用关键帧动画,但这并不是重点。)
(脚注2-当然,使用CADisplayLink以普通的手动方式制作动画通常更好,而不必担心动画,但本QA是关于动画的。)粗略地说,
CoreAnimation
使您能够根据特定的计时功能在特定值之间执行插值
CAAnimation
具有在给定时间将其内插值应用于层的
在draw(在ctx:CGContext中)
方法调用之前的display
方法调用堆栈中,在模型层的类(init(layer:)
调用)的实例中创建了表示层之后,会将该值注入表示层
因此,假设表示层的类与自定义层的类相同,一种解决方法是使动画特性不同于用于渲染层内容的特性。您可以设置interpolatedValue
属性的动画,并具有另一个动态属性strokeEnd
,该属性将在interpolatedValue
值之外的每一帧上动态计算适当的值
在边缘情况下,interpolatedValue
可能只是从0到1的动画进度,基于此,您可以动态计算表示层中的strokeEnd
值。您甚至可以向学员询问给定进度的值:
@objc @NSManaged open dynamic var interpolatedValue: CGFloat
open override class func needsDisplay(forKey key: String) -> Bool {
var result = super.needsDisplay(forKey: key)
result = result || key == "interpolatedValue"
return result
}
open var strokeEnd : CGFloat {
get {
return self.delegate.crazyLayer(self, strokeEndFor: self.interpolatedValue)
}
set {
...
}
}
另一种解决方法是使用
CAKeyframeAnimation
,在其中可以指定在相应时间必须为可设置动画的属性指定的值
如果您可能希望在每一帧上指定插值组件中的一个复杂值,我有一个通过插值其属性为
NSAttributedString
值的动画指定的位置,以及我描述方法的位置。您知道如何暂停动画吗?只要在这里搜索,你就能找到很多信息。嗨@E.Coms!我想你根本不明白这里要问什么。我知道你的意思,但你不能用公共API来做。所以这些方法是不安全的。谢谢,我认为你们的第3段是问题的核心,很好。但我。。。。。。。。。。。。。。。。。不知道怎么做:)例如,你说可以设置插值属性的动画,但我真的不知道在我们所说的内容的同一上下文中的柯德。(对不起!:)也许到时候你可以慷慨地添加更多的kode细节…:请参阅我的文章,这里我展示了如何创建可设置动画的层属性的示例。我会在这里添加一些代码。明白!行。好东西,一流的文章
let animation = CABasicAnimation(keyPath: "interpolatedValue")
animation.duration = 2.0
animation.fromValue = 0.0
animation.toValue = 1.0
crazyLayer.add(animation, forKey: "interpolatedValue")