【问题标题】:Swift, playing multiple animations consecutively from an array?Swift,从一个数组中连续播放多个动画?
【发布时间】: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")
}

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

【问题讨论】:

    标签: swift animation


    【解决方案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)
    }
    
    ...
    

    【讨论】:

    • 这不应该是公认的答案吗?
    猜你喜欢
    • 2022-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-24
    • 2016-07-29
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多