使用偏移量启动 CABasicAnimation
Start CABasicAnimation with an offset
我很难理解 CABasicAnimation
的计时系统,尤其是 beginTime
和 timeOffset
属性。我经历了 this tutorial and questions such as this one,它们都解释了 pausing/resuming 动画的一种方式。尽管如此,我仍然无法弄清楚如何 直接使用偏移 启动动画。
例如,我想在 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)
我很难理解 CABasicAnimation
的计时系统,尤其是 beginTime
和 timeOffset
属性。我经历了 this tutorial and questions such as this one,它们都解释了 pausing/resuming 动画的一种方式。尽管如此,我仍然无法弄清楚如何 直接使用偏移 启动动画。
例如,我想在 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)