同步执行多个动画的最佳方式
Best way to execute multiple animations synchronously
这将是一个 'best way to do' 类的问题。
我知道有多种制作序列动画的方法,但哪种方法更好?
假设我有 3 个动画要执行,一个接一个,所以下一个仅在前一个完成时开始。
我可以用 UIView.animate(withCompletionBlock:)
做到这一点,所以在完成部分我调用第二个,在第二个的 completionBlock 上我调用第三个。
这个特别让我思考:这是 'beautiful' 的方法吗?在另一个中使用 completionBlocks 是否存在任何已知问题?
只是一个想法。在前一个动画完成块中调用动画,可能会使代码有点像厄运金字塔,如果有类似 10 个同步动画,你不觉得吗?
另一种方法是使用 dispatch_after,我根据前一个动画的 NSTimeInterval
调用下一个动画。在这种情况下,可能会导致应用程序崩溃暂停主线程以等待下一个执行,然后再次暂停以执行第三个。
我知道的最后一种方法是我可以使用 NSTimeInterval 来调用下一个动画,但是这个有点像 dispatch_after 选项。
您认为哪种方法最好?
同步执行 3 个或更多视觉动画(等待前一个完成后开始下一个)。
我可能会在我的应用程序中经常使用它,我想以最好的方式启动它。
例子
completionBlocks 中的动画
DispatchQueue.main.async {
UIView.animate(withDuration: 2.0, animations: {
view1.alpha = 1
}, completion: { (_) in
UIView.animate(withDuration: 5.0, animations: {
view2.alpha = 1
}, completion: { (_) in
UIView.animate(withDuration: 2.0, animations: {
view3.alpha = 0
}, completion: { (_) in
UIView.animate(withDuration: 2.0, animations: {
view4.alpha = 0
}, completion: { (_) in
print("all completed")
})
})
})
})
}
与dispatch_after:
let anim1_duration = 2.0
let anim2_duration = 3.0
let anim3_duraiton = 5.0
UIView.animate(withDuration: anim1_duration, animations: {
view1.alpha = 1
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: UInt64(anim1_duration * Double(NSEC_PER_SEC)))) {
UIView.animate(withDuration: anim2_duration, animations: {
view2.alpha = 1
}
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: UInt64((anim1_duration + anim2_duration) * Double(NSEC_PER_SEC)))) {
UIView.animate(withDuration: anim3_duration, animations: {
view3.alpha = 1
}
}
就'better reading code'而言,考虑这两种执行动画的方式:
这些选项避免了我喜欢的完成块。
查看 UIView 的 animateKeyframes(withDuration:delay:options:animations:completion:):
class func animateKeyframes(withDuration duration: TimeInterval,
delay: TimeInterval,
options: UIViewKeyframeAnimationOptions = [],
animations: @escaping () -> Void,
completion: ((Bool) -> Void)? = nil)
对于您的具体情况,它看起来像这样:
UIView.animateKeyframes(withDuration: 20,
delay: 0,
options: [],
animations: {
UIView.addKeyframe(withRelativeStartTime: 0,
relativeDuration: 0.2,
animations: {
view1.alpha = 1
})
UIView.addKeyframe(withRelativeStartTime: 0.2,
relativeDuration: 0.3,
animations: {
view2.alpha = 1
})
UIView.addKeyframe(withRelativeStartTime: 0.5,
relativeDuration: 0.1,
animations: {
view3.alpha = 0
})
UIView.addKeyframe(withRelativeStartTime: 0.6,
relativeDuration: 0.4,
animations: {
view4.alpha = 0
})
},
completion: nil)
这将是一个 'best way to do' 类的问题。
我知道有多种制作序列动画的方法,但哪种方法更好?
假设我有 3 个动画要执行,一个接一个,所以下一个仅在前一个完成时开始。
我可以用 UIView.animate(withCompletionBlock:)
做到这一点,所以在完成部分我调用第二个,在第二个的 completionBlock 上我调用第三个。
这个特别让我思考:这是 'beautiful' 的方法吗?在另一个中使用 completionBlocks 是否存在任何已知问题?
只是一个想法。在前一个动画完成块中调用动画,可能会使代码有点像厄运金字塔,如果有类似 10 个同步动画,你不觉得吗?
另一种方法是使用 dispatch_after,我根据前一个动画的 NSTimeInterval
调用下一个动画。在这种情况下,可能会导致应用程序崩溃暂停主线程以等待下一个执行,然后再次暂停以执行第三个。
我知道的最后一种方法是我可以使用 NSTimeInterval 来调用下一个动画,但是这个有点像 dispatch_after 选项。
您认为哪种方法最好? 同步执行 3 个或更多视觉动画(等待前一个完成后开始下一个)。
我可能会在我的应用程序中经常使用它,我想以最好的方式启动它。
例子
completionBlocks 中的动画
DispatchQueue.main.async {
UIView.animate(withDuration: 2.0, animations: {
view1.alpha = 1
}, completion: { (_) in
UIView.animate(withDuration: 5.0, animations: {
view2.alpha = 1
}, completion: { (_) in
UIView.animate(withDuration: 2.0, animations: {
view3.alpha = 0
}, completion: { (_) in
UIView.animate(withDuration: 2.0, animations: {
view4.alpha = 0
}, completion: { (_) in
print("all completed")
})
})
})
})
}
与dispatch_after:
let anim1_duration = 2.0
let anim2_duration = 3.0
let anim3_duraiton = 5.0
UIView.animate(withDuration: anim1_duration, animations: {
view1.alpha = 1
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: UInt64(anim1_duration * Double(NSEC_PER_SEC)))) {
UIView.animate(withDuration: anim2_duration, animations: {
view2.alpha = 1
}
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: UInt64((anim1_duration + anim2_duration) * Double(NSEC_PER_SEC)))) {
UIView.animate(withDuration: anim3_duration, animations: {
view3.alpha = 1
}
}
就'better reading code'而言,考虑这两种执行动画的方式:
这些选项避免了我喜欢的完成块。
查看 UIView 的 animateKeyframes(withDuration:delay:options:animations:completion:):
class func animateKeyframes(withDuration duration: TimeInterval,
delay: TimeInterval,
options: UIViewKeyframeAnimationOptions = [],
animations: @escaping () -> Void,
completion: ((Bool) -> Void)? = nil)
对于您的具体情况,它看起来像这样:
UIView.animateKeyframes(withDuration: 20,
delay: 0,
options: [],
animations: {
UIView.addKeyframe(withRelativeStartTime: 0,
relativeDuration: 0.2,
animations: {
view1.alpha = 1
})
UIView.addKeyframe(withRelativeStartTime: 0.2,
relativeDuration: 0.3,
animations: {
view2.alpha = 1
})
UIView.addKeyframe(withRelativeStartTime: 0.5,
relativeDuration: 0.1,
animations: {
view3.alpha = 0
})
UIView.addKeyframe(withRelativeStartTime: 0.6,
relativeDuration: 0.4,
animations: {
view4.alpha = 0
})
},
completion: nil)