如何在Swift中制作绘图动画,还能改变UIImageView的缩放比例?

jbb*_*nni 2 animation core-animation uiimageview ios swift

我想为绘图序列制作动画.我的代码将螺旋绘制到UIImageView.image中.序列会更改图像内容,但也会更改周围UIImageView 的比例.代码参数化为螺旋的转数:

func drawSpiral(rotations:Double) {
let scale = scaleFactor(rotations)   // do some math to figure the best scale

UIGraphicsBeginImageContextWithOptions(mainImageView.bounds.size, false, 0.0)
let context = UIGraphicsGetCurrentContext()!
context.scaleBy(x: scale, y: scale)      // some animation prohibits changes!
// ...  drawing happens here
myUIImageView.image = UIGraphicsGetImageFromCurrentImageContext()
}
Run Code Online (Sandbox Code Playgroud)

例如,我想从动画drawSpiral(2.0)drawSpiral(2.75)在20个递增,在1.0秒的持续时间.

我可以设置UIView.annimate(withDuration...)使用连续的中间值调用我的方法吗?怎么样?有更好的动画方法吗?

mat*_*att 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!
    }
}
Run Code Online (Sandbox Code Playgroud)

该层实际上必须位于界面中,但用户无法看到:

let lay = MyLayer()
lay.frame = CGRect(x: 0, y: 0, width: 1, height: 1)
self.view.layer.addSublayer(lay)
Run Code Online (Sandbox Code Playgroud)

随后,我们可以初始化spirality图层:

lay.spirality = 2.0
lay.setNeedsDisplay() // prints: 2.0
Run Code Online (Sandbox Code Playgroud)

现在,当我们想要"动画化"时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
Run Code Online (Sandbox Code Playgroud)

控制台显示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
Run Code Online (Sandbox Code Playgroud)

这些正是这将在动画的财产被抛出,当您更改视图的框架起源如数字x来自22.75在1秒持续时间的动画.但现在数字会以数字的形式出现在你身上,所以你现在可以用这一系列的数字做任何你喜欢的事情.如果您想在每个新值到达时调用您的方法,请立即前进.