我在理解CABasicAnimation
的计时系统时遇到了麻烦,尤其是beginTime
和timeOffset
属性。我经历了this tutorial和诸如this one之类的问题,它们都解释了暂停/恢复动画的方式。不过,我仍然不知道如何直接从偏移开始动画。
例如,我想以2.0秒开始我的动画,这意味着如果我的动画是从白色到黑色的颜色过渡(持续时间为3.0秒,那么动画将从深灰色开始并在过渡到黑色)。 1.0秒
我无法使用UIViewPropertyAnimator
,因为我的动画是关于更改渐变(CAGradientLayer
)的颜色的。
当将动画添加到图层时,如何以所需的偏移量开始动画?
要直接以偏移量开始CABasicAnimation
,就像将其timeOffset
设置为您要动画开始的时间线中的时间一样简单。
因此,例如,如果动画的duration
设置为3,并且timeOffset
设置为2,则动画将(明显地)在动画开始2秒后开始。
但是,这不会阻止动画然后回绕以完成被跳过的动画部分(从0到2秒)。如果希望动画在到达toValue
之后停止播放,可以将repeatDuration
设置为1以在1秒钟后切断动画。
这是一个完整的Playground示例,您可以在其中使用动画属性,然后单击实时视图以查看动画:
import UIKit
import PlaygroundSupport
class GradientView: UIView {
override class var layerClass: AnyClass {
CAGradientLayer.self
}
override var layer: CAGradientLayer {
super.layer as! CAGradientLayer
}
override init(frame: CGRect) {
super.init(frame: frame)
layer.colors = [UIColor.white.cgColor, UIColor.white.cgColor]
layer.locations = [0, 1]
let tap = UITapGestureRecognizer(target: self,
action: #selector(animateGradient))
addGestureRecognizer(tap)
}
required init?(coder: NSCoder) {
fatalError("Not implemented")
}
@objc func animateGradient() {
// Animate the `colors` property of the gradient layer.
// In this example we're just animating the first color of
// a two-color gradient.
let anim = CABasicAnimation(keyPath: "colors")
anim.fromValue = [UIColor.white.cgColor, UIColor.white.cgColor]
anim.toValue = [UIColor.black.cgColor, UIColor.white.cgColor]
// Sets the length of the animation's timeline.
//
// Note that in this case, this is not the _effective_ duration
// as we are stopping the animation after 1 second due to setting
// `repeatDuration` below.
anim.duration = 3
// Where in the animation's timeline the animation should
// effectively start.
//
// In this case, this starts the animation 2 seconds in to the
// timeline, which makes it look like the first gradient color
// immediately starts at dark gray.
anim.timeOffset = 2
// Stops the animation when it gets to the `toValue`.
// This makes the effective duration 1 second long.
//
// Comment this out to let the animation loop back around
// so that it then fades from white to dark gray, if desired.
anim.repeatDuration = anim.duration - anim.timeOffset
layer.add(anim, forKey: nil)
}
}
let gradientViewFrame = CGRect(x: 0, y: 0, width: 200, height: 200)
PlaygroundPage.current.liveView = GradientView(frame: gradientViewFrame)