同步执行多个动画的最佳方式

时间:2017-03-28 22:26:32

标签: ios animation swift3 uiviewanimation

这将是一个“最好的方式”问题。

我知道有多种方法可以进行序列动画,但哪一种更好的方法呢?

假设我有3个动画,我正在尝试执行,一个接一个,所以下一个只在前一个完成后才开始。

我可以用UIView.animate(withCompletionBlock:)来完成,所以在完成部分我调用第二个,在第二个的完成块上,我称之为第三个。

这个特别让我想到:这是一种“美丽”的方式吗?在另一个中使用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
        }
    }

2 个答案:

答案 0 :(得分:3)

查看UIView的animate​Keyframes(with​Duration:​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)

答案 1 :(得分:0)

就“更好的阅读代码”而言,请考虑以下两种执行动画的方式:

  1. 构建动画堆栈:more

  2. 使用CAKeyframeAnimation创建关键帧动画:more

  3. 这些选项避免了我喜欢的完成块。

相关问题