如何对两个动画之间的延迟进行排序
How to sequence two animations with delay in between
我有一个UIImageView
,我想旋转180度,占用1秒,然后我想在这个位置等1秒,然后旋转180度回到原来的位置,占用1秒.
我该如何做到这一点?我已经尝试了 100 种方法,它一直在回弹而不是向后旋转
编辑:我忘了添加我需要这个无限期地重复
您可以在 UIView.animate
上呈现的 completionHandler 中执行第二个动画
let duration = self.transitionDuration(using: transitionContext)
let firstAnimDuration = 0.5
UIView.animate(withDuration: firstAnimDuration, animations: {
/* Do here the first animation */
}) { (completed) in
let secondAnimDuration = 0.5
UIView.animate(withDuration: secondAnimDuration, animations: {
/* Do here the second animation */
})
}
现在你可能遇到了另一个问题。
如果您使用 CGAffineTransform 旋转您的视图,并且为每个动画分配一个这种类型的新对象给您的 view.transform,您将失去之前的变换操作
所以,根据这个post:,你需要concat转换操作
带有 2 个动画块的示例
这是旋转180度并在1秒后返回原点的示例:
let view = UIView.init(frame: CGRect.init(origin: self.view.center, size: CGSize.init(width: 100, height: 100)))
view.backgroundColor = UIColor.red
self.view.addSubview(view)
var transform = view.transform
transform = transform.rotated(by: 180)
UIView.animate(withDuration: 2, animations: {
view.transform = transform
}) { (completed) in
transform = CGAffineTransform.identity
UIView.animate(withDuration: 2, delay: 1, options: [], animations: {
view.transform = transform
}, completion: nil)
}
.repeat 动画和 .autoreverse 示例
.animate 方法使您能够设置一些动画选项。特别是结构 UIViewAnimationOptions 包含:
- .repeat,无限重复你的动画块
- .autoreverse,将您的视图恢复到原始状态
考虑到这一点,您可以这样做:
var transform = view.transform.rotated(by: 180)
UIView.animate(withDuration: 2, delay: 0, options: [.repeat, .autoreverse], animations: {
self.myView.transform = transform
})
但是你需要在两个动画之间有一个延迟,所以你需要做这个技巧:
递归动画示例和 1 秒的延迟
只需在您的 ViewController 中创建一个方法来激活您的视图。在最后的completionHandler中,直接调用方法创建一个无限循环。
最后需要调用viewDidAppear的方法来启动动画。
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.animation()
}
func animation() {
var transform = view.transform
transform = transform.rotated(by: 180)
UIView.animate(withDuration: 2, delay: 0, options: [], animations: {
self.myView.transform = transform
}) { bool in
transform = CGAffineTransform.identity
UIView.animate(withDuration: 2, delay: 1, options: [], animations: {
self.myView.transform = transform
}, completion: { bool in
self.animation()
})
}
}
您只需创建一个 keyFrame animations。它旨在将多个动画链接在一起,并在第一个关键帧中将 UIImageView
子类旋转 PI
,在第二个关键帧中将其转换回 identity
.
let rotateForwardAnimationDuration: TimeInterval = 1
let rotateBackAnimationDuration: TimeInterval = 1
let animationDuration: TimeInterval = rotateForwardAnimationDuration + rotateBackAnimationDuration
UIView.animateKeyframes(withDuration: animationDuration, delay: 0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: rotateForwardAnimationDuration) {
self.imageView.transform = CGAffineTransform(rotationAngle: .pi)
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: rotateBackAnimationDuration) {
self.imageView.transform = .identity
}
})
结果:
编辑:
这是一个如何使它无限期地 运行 的例子。我想您的图片在 viewController 中,并且您持有对 imageView 的一些引用。
因此,例如,在 viewDidAppear
上调用触发动画的函数,然后在动画的完成块中再次调用相同的函数。
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.runRotateAnimation()
}
func runRotateAnimation() {
let rotateForwardAnimationDuration: TimeInterval = 1
let rotateBackAnimationDuration: TimeInterval = 1
let animationDuration: TimeInterval = rotateForwardAnimationDuration + rotateBackAnimationDuration
UIView.animateKeyframes(withDuration: animationDuration, delay: 0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: rotateForwardAnimationDuration) {
self.imageView.transform = CGAffineTransform(rotationAngle: .pi)
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: rotateBackAnimationDuration) {
self.imageView.transform = .identity
}
}) { (isFinished) in
// To loop it continuosly, just call the same function from the completion block of the keyframe animation
self.runRotateAnimation()
}
}
}
我有一个UIImageView
,我想旋转180度,占用1秒,然后我想在这个位置等1秒,然后旋转180度回到原来的位置,占用1秒.
我该如何做到这一点?我已经尝试了 100 种方法,它一直在回弹而不是向后旋转
编辑:我忘了添加我需要这个无限期地重复
您可以在 UIView.animate
上呈现的 completionHandler 中执行第二个动画let duration = self.transitionDuration(using: transitionContext)
let firstAnimDuration = 0.5
UIView.animate(withDuration: firstAnimDuration, animations: {
/* Do here the first animation */
}) { (completed) in
let secondAnimDuration = 0.5
UIView.animate(withDuration: secondAnimDuration, animations: {
/* Do here the second animation */
})
}
现在你可能遇到了另一个问题。
如果您使用 CGAffineTransform 旋转您的视图,并且为每个动画分配一个这种类型的新对象给您的 view.transform,您将失去之前的变换操作
所以,根据这个post:
带有 2 个动画块的示例
这是旋转180度并在1秒后返回原点的示例:
let view = UIView.init(frame: CGRect.init(origin: self.view.center, size: CGSize.init(width: 100, height: 100)))
view.backgroundColor = UIColor.red
self.view.addSubview(view)
var transform = view.transform
transform = transform.rotated(by: 180)
UIView.animate(withDuration: 2, animations: {
view.transform = transform
}) { (completed) in
transform = CGAffineTransform.identity
UIView.animate(withDuration: 2, delay: 1, options: [], animations: {
view.transform = transform
}, completion: nil)
}
.repeat 动画和 .autoreverse 示例
.animate 方法使您能够设置一些动画选项。特别是结构 UIViewAnimationOptions 包含:
- .repeat,无限重复你的动画块
- .autoreverse,将您的视图恢复到原始状态
考虑到这一点,您可以这样做:
var transform = view.transform.rotated(by: 180)
UIView.animate(withDuration: 2, delay: 0, options: [.repeat, .autoreverse], animations: {
self.myView.transform = transform
})
但是你需要在两个动画之间有一个延迟,所以你需要做这个技巧:
递归动画示例和 1 秒的延迟
只需在您的 ViewController 中创建一个方法来激活您的视图。在最后的completionHandler中,直接调用方法创建一个无限循环。
最后需要调用viewDidAppear的方法来启动动画。
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.animation()
}
func animation() {
var transform = view.transform
transform = transform.rotated(by: 180)
UIView.animate(withDuration: 2, delay: 0, options: [], animations: {
self.myView.transform = transform
}) { bool in
transform = CGAffineTransform.identity
UIView.animate(withDuration: 2, delay: 1, options: [], animations: {
self.myView.transform = transform
}, completion: { bool in
self.animation()
})
}
}
您只需创建一个 keyFrame animations。它旨在将多个动画链接在一起,并在第一个关键帧中将 UIImageView
子类旋转 PI
,在第二个关键帧中将其转换回 identity
.
let rotateForwardAnimationDuration: TimeInterval = 1
let rotateBackAnimationDuration: TimeInterval = 1
let animationDuration: TimeInterval = rotateForwardAnimationDuration + rotateBackAnimationDuration
UIView.animateKeyframes(withDuration: animationDuration, delay: 0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: rotateForwardAnimationDuration) {
self.imageView.transform = CGAffineTransform(rotationAngle: .pi)
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: rotateBackAnimationDuration) {
self.imageView.transform = .identity
}
})
结果:
编辑: 这是一个如何使它无限期地 运行 的例子。我想您的图片在 viewController 中,并且您持有对 imageView 的一些引用。
因此,例如,在 viewDidAppear
上调用触发动画的函数,然后在动画的完成块中再次调用相同的函数。
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.runRotateAnimation()
}
func runRotateAnimation() {
let rotateForwardAnimationDuration: TimeInterval = 1
let rotateBackAnimationDuration: TimeInterval = 1
let animationDuration: TimeInterval = rotateForwardAnimationDuration + rotateBackAnimationDuration
UIView.animateKeyframes(withDuration: animationDuration, delay: 0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: rotateForwardAnimationDuration) {
self.imageView.transform = CGAffineTransform(rotationAngle: .pi)
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: rotateBackAnimationDuration) {
self.imageView.transform = .identity
}
}) { (isFinished) in
// To loop it continuosly, just call the same function from the completion block of the keyframe animation
self.runRotateAnimation()
}
}
}