Swift,从一个数组中连续播放多个动画?

Posted

技术标签:

【中文标题】Swift,从一个数组中连续播放多个动画?【英文标题】:Swift, playing multiple animations consecutively from an array? 【发布时间】:2018-09-18 23:15:09 【问题描述】:

对不起,我是 swift 新手。我不能让每个动画连续播放,而不是一次全部播放。我曾尝试使用 sleep(),但这似乎不允许动画播放。这就是我找到要播放的动画的方法。

for number in sequence 
    switch number 
    case 1:
        print("blue")
        animateB()
    case 2:
        print("green")
        animateG()
    case 3:
        print("magenta")
        animateM()
    case 4:
        print("orange")
        animateO()
    case 5:
        print("yellow")
        animateY()
    case 6:
        print("red")
        animateR()
    case 7:
        print("purple")
        animateP()
    case 8:
        print("cyan")
        animateC()
    default:
        print("error")
    

这是我用来制作动画的功能之一。我意识到这也可能非常低效,但不确定如何使功能更好。

private func animateB()
    let animation = CABasicAnimation(keyPath: "transform.scale")
    animation.toValue = 1.3
    animation.duration = 0.5
    animation.autoreverses = true
    self.pulsatingB.add(animation, forKey: "pulsing")

任何帮助将非常感谢。 :)

【问题讨论】:

【参考方案1】:

您可以使用CATransaction 链接CAAnimations:

class ViewController: UIViewController 

    // The animations, to be applied in order
    var animationQueue = [() -> Void]()

    @IBAction func animate(_ sender: Any) 

        animationQueue.removeAll()

        // Build the animation queue
        for number in sequence 
            switch number 
            case 1:
                print("blue")
                animationQueue.append(animateB)
            case 2:
                print("green")
                animationQueue.append(animateG)
            // ....
            default:
                break
            
        

        // Start the animation
        applyNextAnimation()
    

    func applyNextAnimation() 
        guard !animationQueue.isEmpty else  return 
        let animation = animationQueue.removeFirst()

        // When an animation completes, call this function again to apply the next animation
        CATransaction.begin()
        CATransaction.setCompletionBlock( self.applyNextAnimation() )
        animation()
        CATransaction.commit()
    


【讨论】:

好答案。 (已投票。)然而,for 循环和 switch 语句似乎没有多大意义。为什么不只是animationQueue = [animateB, animateC, animateD, animateE, animateF, animateG] @DuncanC 同意了。我的想法是解决顺序动画问题。没有停下来思考 for 循环和开关 你应该编辑你的答案。这样会更干净。 谢谢它的工作。我仍在使用 for 循环和 switch 语句。【参考方案2】:

对于动画序列,基于块的关键帧动画通常也可以完成这项工作,例如:

UIView.animateKeyframes(withDuration: 4.0, delay: 0, options: .repeat, animations: 
    UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.25, animations: 
        self.subview.transform = .init(scaleX: 0.5, y: 0.5)
    )

    UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.25, animations: 
        self.subview.transform = .init(scaleX: 1.3, y: 1.3)
    )

    UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.25, animations: 
        self.subview.transform = .init(scaleX: 0.75, y: 0.75)
    )

    UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 0.25, animations: 
        self.subview.transform = .identity
    )
, completion: nil)

或者,如果你有一个函数数组:

let animations = [animateA, animateB, animateC, animateD]

UIView.animateKeyframes(withDuration: 4.0, delay: 0, options: .repeat, animations: 
    for (index, animation) in animations.enumerated() 
        UIView.addKeyframe(withRelativeStartTime: Double(index) / Double(animations.count), relativeDuration: 1 / Double(animations.count), animations: 
            animation()
        )
    
, completion: nil)

在哪里,

func animateA() 
    subview.transform = .init(scaleX: 0.5, y: 0.5)


func animateB() 
    subview.transform = .init(scaleX: 1.3, y: 1.3)


...

【讨论】:

这不应该是公认的答案吗?

以上是关于Swift,从一个数组中连续播放多个动画?的主要内容,如果未能解决你的问题,请参考以下文章

Swift:重复的连续 CABasicAnimations

Swift 3 数组 - 在其他数组的帮助下删除多个元素

使用完成处理程序在 Swift 中调用连续动画

从浮点数组iOS Swift播放音频

从字符串数组 Swift 播放声音

如何在 Swift 中连续录制音频并播放同一文件中的音频?