且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在 Swift 中为绘图设置动画,同时更改 UIImageView 的比例?

更新时间:2023-01-04 08:59:21

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

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

动画只是一连串定时的中间值被扔到某物上.要求将它们扔到您的代码中是完全合理的,这样您就可以对它们做任何您喜欢的事情.方法如下.

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.

你需要一个特殊的层:

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)

接下来,我们可以初始化层的spirality:

Subsequently, we can initialize the spirality of the layer:

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

现在,当我们想要动画"spirality 时,我们会这样做:

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

这些正是将在动画属性中抛出的数字,例如当您将视图的框架原点 x2 更改为 2.75代码> 在 1 秒持续时间的动画中.但是现在数字以数字的形式出现在您面前,因此您现在可以用这一系列数字做任何您喜欢的事情.如果您想在每个新值到达时调用您的方法,请继续.

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.