如何在Swift中为绘图动画,还可以更改UIImageView的比例? [英] How to animate drawing in Swift, but also change a UIImageView's scale?

查看:97
本文介绍了如何在Swift中为绘图动画,还可以更改UIImageView的比例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为绘图序列设置动画。我的代码使UIImageView.image呈螺旋形。该序列会更改图像内容,但也会更改周围UIImageView的 scale 。代码针对螺旋的转数进行了参数化:

I'd like to animate a drawing sequence. My code draws a spiral into a UIImageView.image. The sequence changes the image contents, but also changes the scale of the surrounding UIImageView. The code is parameterized for the number of revolutions of the spiral:

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()
}

例如,我想从 drawSpir​​al(2.0)动画到 drawSpir​​al(2.75)以20增量,持续1.0秒。

For example, I'd like to animate from drawSpiral(2.0) to drawSpiral(2.75) in 20 increments, over a duration of 1.0 seconds.

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

Can I setup UIView.annimate(withDuration...) to call my method with successive intermediate values? How? Is there a better animation approach?

推荐答案


我可以设置UIView.annimate(withDuration ... )以连续的中间值调用我的方法

Can I setup UIView.annimate(withDuration...) to call my method with successive intermediate values

Animation 只是一系列定时中间值被抛出在某事上。要求将它们扔到您的代码上是完全合理的,以便您可以对它们进行任何操作。

Animation is merely a succession of timed intermediate values being thrown at something. It is perfectly reasonable to ask that they be thrown at your code so that you can do whatever you like with them. Here's how.

您需要一个特殊的图层:

You'll need a special layer:

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!
    }
}

该图层实际上必须在界面中用户可能看不到:

The layer must actually be in the interface, though it can be impossible for the user to see:

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

随后,我们可以初始化图层的灵性

Subsequently, we can initialize the spirality of the layer:

lay.spirality = 2.0
lay.setNeedsDisplay() // prints: 2.0

现在,当我们要动画化 螺旋形 c时,这就是我们要做的事情:

Now when we want to "animate" the spirality, this is what we do:

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秒内一系列中间值的到达!

The console shows the arrival of a succession of intermediate values over the course of 1 second!

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 在1秒钟的动画中变为 2.75 。但是现在数字以数字的形式出现在您身上,因此您现在可以使用该系列数字做任何您想做的。如果要在到达每个新值时调用方法,请继续。

Those are exactly the numbers that would be thrown at an animatable property, such as when you change a view's frame origin x from 2 to 2.75 in a 1-second duration animation. But now the numbers are coming to you as numbers, and so you can now do anything you like with that series of numbers. If you want to call your method with each new value as it arrives, go right ahead.

这篇关于如何在Swift中为绘图动画,还可以更改UIImageView的比例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆