我想为绘图序列制作动画。我的代码将螺旋绘制到UIImageView.image中。序列更改图像内容,但也更改周围UIImageView的比例。代码参数化为螺旋的转数:
drawSpiral(2.0)
例如,我希望在1.0秒的持续时间内以20个为增量从drawSpiral(2.75)
动画到UIView.annimate(withDuration...)
。
我可以设置{{1}}以使用连续的中间值调用我的方法吗?怎么样?有更好的动画方法吗?
答案 0 :(得分:5)
我可以设置UIView.annimate(withDuration ...)来使用连续的中间值调用我的方法
动画 仅仅是一系列定时中间值被抛出的东西。要求他们抛出你的代码是完全合理的,这样你就可以随心所欲地做任何事。这是怎么回事。
您需要一个特殊的图层:
class MyLayer : CALayer {
@objc var spirality : CGFloat = 0
override class func needsDisplay(forKey key: String) -> Bool {
if key == #keyPath(spirality) {
return true
}
return super.needsDisplay(forKey:key)
}
override func draw(in con: CGContext) {
print(self.spirality) // in real life, this is our signal to draw!
}
}
该层实际上必须位于界面中,但用户无法看到:
let lay = MyLayer()
lay.frame = CGRect(x: 0, y: 0, width: 1, height: 1)
self.view.layer.addSublayer(lay)
随后,我们可以初始化图层的spirality
:
lay.spirality = 2.0
lay.setNeedsDisplay() // prints: 2.0
现在我们想要"动画" spirality
,这就是我们所做的:
let ba = CABasicAnimation(keyPath:#keyPath(MyLayer.spirality))
ba.fromValue = lay.spirality
ba.toValue = 2.75
ba.duration = 1
lay.add(ba, forKey:nil)
CATransaction.setDisableActions(true)
lay.spirality = 2.75
控制台在1秒钟内显示一系列中间值的到来!
2.03143266495317
2.04482554644346
2.05783333256841
2.0708108600229
2.08361491002142
2.0966724678874
2.10976020619273
2.12260236591101
2.13551922515035
2.14842618256807
2.16123360767961
2.17421661689878
2.18713565543294
2.200748950243
2.21360073238611
2.2268518730998
2.23987507075071
2.25273013859987
2.26560932397842
2.27846492826939
2.29135236144066
2.30436328798532
2.31764804571867
2.33049770444632
2.34330793470144
2.35606706887484
2.36881992220879
2.38163591921329
2.39440815150738
2.40716737508774
2.42003352940083
2.43287514150143
2.44590276479721
2.45875595510006
2.47169743478298
2.48451870679855
2.49806520342827
2.51120449602604
2.52407149970531
2.53691896796227
2.54965999722481
2.56257836520672
2.57552136480808
2.58910304307938
2.60209316015244
2.6151298135519
2.62802086770535
2.64094598591328
2.6540260463953
2.6669240295887
2.6798157542944
2.69264766573906
2.70616912841797
2.71896715462208
2.73285858333111
2.74564798176289
2.75
2.75
2.75
这些正是在可动画属性中抛出的数字,例如当您将视图的帧起源x
从2
更改为2.75
时 - 第二次持续时间动画。但是现在数字会以数字的形式出现在你身上,所以现在你可以用这一系列的数字做你喜欢的任何事情。如果您想在每个新值到达时调用您的方法,请直接前进。
答案 1 :(得分:1)
Personally, in more complicated animations I would use lottie the animation itself is built with Adobe After Effect and exported as a JSON file which you will manage using the lottie library this approach will save you time and effort when you port your app to another platform like Android as they also have an Android Lottie which means the complicated process of creating the animation is only done once.
Lottie Files has some examples animations as well for you to look.
答案 2 :(得分:0)
CABasicAnimation(keyPath:)
。myView.layer.addSublayer(myLayer)
override class func needsDisplay(forKey key: String) -> Bool
(如@Matt的示例所示),以及override func draw(in cxt: CGContext)
进行绘图。请务必使用@objc
修饰您的密钥属性。 并参考图纸代码中的关键属性。 override func draw(_ rect: CGRect) { }
)置空,以避免单独图层上的动画和非动画绘图之间发生冲突。为了在同一个UIView中协调动画和非动画内容,从自定义层执行 all 绘图是很好的(必要吗?)。 myLayer.setNeedsDisplay()
更新自定义图层中的非动画内容;使用myLayer.add(myBasicAnimation, forKey:nil)
触发自定义图层中的动画绘制。正如我上面所说,@马特回答 - 但这些项目似乎值得强调。