swift 3 uiview animate 只显示最后两个动画

swift 3 uiview animate only showing last two animations

试图让我的弹出式 UIView 的背景颜色在 4 种颜色之间变化,然后循环并重复。对于下面的代码,只有最后两种颜色出现,前两种颜色被跳过,我已经尝试了所有我能想到的,知道我错过了什么吗?

     UIView.animateWithDuration(2, delay: 0.0, options:[UIViewAnimationOptions.Repeat, UIViewAnimationOptions.Autoreverse], animations: {
        self.view.backgroundColor = UIColor.blackColor()
        self.view.backgroundColor = UIColor.greenColor()
        self.view.backgroundColor = UIColor.grayColor()
        self.view.backgroundColor = UIColor.redColor()
    }, completion: nil)

更新代码:

     UIView.animate(withDuration: 12, delay: 1, options:
                [UIViewAnimationOptions.allowUserInteraction,
                 UIViewAnimationOptions.repeat,
                 UIViewAnimationOptions.autoreverse],
                                       animations: {
                                        self.popupView.backgroundColor = UIColor.black
                                        self.popupView.backgroundColor = UIColor.green
                                        self.popupView.backgroundColor = UIColor.gray
                                        self.popupView.backgroundColor = UIColor.red
            }, completion:nil )

更新 2:单个动画块:

     UIView.animate(withDuration: 3, delay: 0.0, options:
       [UIViewAnimationOptions.repeat, 
        UIViewAnimationOptions.autoreverse, 
       .allowUserInteraction], 
       animations: { (BOOL) -> Void in

                self.popupView.backgroundColor = UIColor.black
            }) { (Bool) -> Void in
                UIView.animate(withDuration: 3.0, animations: { () -> Void in
                    self.popupView.backgroundColor = UIColor.green
                }, completion: { (Bool) -> Void in
                    UIView.animate(withDuration: 3.0, animations: { () -> Void in
                        self.popupView.backgroundColor = UIColor.gray
                    }, completion: { (Bool) -> Void in
                        UIView.animate(withDuration: 3.0, animations: { () -> Void in
                            self.popupView.backgroundColor = UIColor.white
                        }, completion:nil)
                    })
                })
            }

首先,动画块中的颜色变化不会动画颜色变化。但是如果你只想改变颜色,使用动画块可能没问题。

要使用动画块获得您想要的结果,代码应如下所示。

UIView.animate(withDuration: 12, delay: 1, options:
            [.allowUserInteraction, .repeat, .autoreverse],
                                   animations: {
                                    self.popupView.backgroundColor = UIColor.black
        }, completion:{ competed in
            UIView.animate(withDuration: 12, delay: 1, options:
            [.allowUserInteraction, .repeat, .autoreverse],
                                   animations: {
                                    self.popupView.backgroundColor = UIColor.green
            }, completion: .... )

如果你只想每 N 秒改变一次背景颜色,你最好使用定时器。

更新

下面是一个使用定时器的例子。

class MyViewController : UIViewController {
    var timer: Timer?
    let colors: [UIColor] = [.white, .black, .red, .magenta]
    var idx: Int = 0

    deinit {
        timer?.invalidate()
        timer = nil
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        timer = Timer(timeInterval: 5,
                      target: self,
                      selector: #selector(changeColor),
                      userInfo: nil,
                      repeats: true)
    }

    @objc
    func changeColor() {
        view.backgroundColor = colors[idx]
        idx = (idx + 1) % colors.count
    }
}

使用计时器将使您的代码更简单。

首先,backgroundColor 不可设置动画。但是如果它 ,或者如果你想为 可动画的东西制作动画,循环多个动画的更好方法是使用关键帧动画,像这样:

UIView.animateKeyframes(withDuration: 12, delay: 0, options: [.allowUserInteraction, .repeat, .autoreverse], animations: {
    UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.25, animations: {
        self.popupView.backgroundColor = .black
    })
    UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.25, animations: {
        self.popupView.backgroundColor = .green
    })
    UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.25, animations: {
        self.popupView.backgroundColor = .gray
    })
    UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 0.25, animations: {
        self.popupView.backgroundColor = .red
    })
}, completion: nil)

在这种情况下,我将每个关键帧的 relativeDuration 设置为总动画时间的 0.25 (1/4),并将 relativeStartTime 设置为 beginning, 1/4, 1 /2,总持续时间的 3/4。

再次重申,这不是可动画的 属性,但这是将动画链接在一起的有效方法。

它也 可以通过使用 transition 而不是 animate 来动画颜色变化,尽管你不能进行关键帧转换。您可以使用完成将它们链接在一起,当您到达终点时,您必须通过调用一些包装函数或类似的东西重新开始动画:

UIView.transition(with: self.popupView, duration: 3, options: .allowUserInteraction, animations: {
    self.popupView.backgroundColor = .black
}, completion: { (finished) in
    UIView.transition(with: self.popupView, duration: 3, options: .allowUserInteraction, animations: {
        self.popupView.backgroundColor = .green
    }, completion: { (finished) in
        UIView.transition(with: self.popupView, duration: 3, options: .allowUserInteraction, animations: {
            self.popupView.backgroundColor = .gray
        }, completion: { (finished) in
            UIView.transition(with: self.popupView, duration: 3, options: .allowUserInteraction, animations: {
                self.popupView.backgroundColor = .red
            }, completion: { (finished) in
                //Start the chain over again
            })
        })
    })
})