动画重复时更改视图的颜色

时间:2015-08-20 21:41:15

标签: ios objective-c swift user-interface animation

我有一个模拟"脉冲"视图,它首先将其转换为无限小(不可见)然后再生长。

func addPulsing() {
    println("Added")
    let pulsing = CAKeyframeAnimation(keyPath: "transform.scale")

    pulsing.duration = 0.8

    pulsing.values = [1.0,0.0,1.0]
    pulsing.keyTimes = [0.0,0.4,0.8]

    pulsing.removedOnCompletion = false
    pulsing.repeatCount = HUGE
    pulsing.calculationMode = kCAAnimationPaced



    let layer = customView.layer
    layer.addAnimation(pulsing, forKey: "pulsing")
}

我想在每次动画重复时更改视图的颜色。我该怎么做 ?我尝试使用计时器,但它与动画失去了同步。

更新:

试图做这样的事情:

    UIView.animateKeyframesWithDuration(3.2, delay: 0, options: .CalculationModePaced | .Repeat, animations: { () -> Void in
        UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.transform = transform
        })
        UIView.addKeyframeWithRelativeStartTime(0.4, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.transform = identity
            self.customView.backgroundColor = self.colors[1]
        })
        UIView.addKeyframeWithRelativeStartTime(0.8, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.transform = transform
        })
        UIView.addKeyframeWithRelativeStartTime(1.2, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.transform = identity
            self.customView.backgroundColor = self.colors[2]
        })
        UIView.addKeyframeWithRelativeStartTime(1.6, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.transform = transform
        })
        UIView.addKeyframeWithRelativeStartTime(2.0, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.transform = identity
            self.customView.backgroundColor = self.colors[3]
        })
        UIView.addKeyframeWithRelativeStartTime(2.4, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.transform = transform
        })
        UIView.addKeyframeWithRelativeStartTime(2.8, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.transform = identity
            self.customView.backgroundColor = self.colors[0]
        })
    }, completion: nil)

仍然无法按需工作。在细节上,动画都是跳跃的而不是平滑的,有些部分比较慢,而其他部分则太快。当视图缩小到0刻度时,我希望颜色立即改变,然后以新的背景颜色开始增长。

然后我尝试创建两个单独的动画。一个用于比例,一个用于颜色。我将颜色设为离散,以便立即改变颜色。所以我得到了:

    let transform = CGAffineTransformScale(customView.transform, 0, 0)
    let identity = CGAffineTransformIdentity

        UIView.animateKeyframesWithDuration(0.8, delay: 0, options: .CalculationModePaced | .Repeat, animations: { () -> Void in
        UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.transform = transform
        })
        UIView.addKeyframeWithRelativeStartTime(0.4, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.transform = identity
        })
    }, completion: nil)


    UIView.animateKeyframesWithDuration(2.8, delay: 0, options: .CalculationModeDiscrete | .Repeat, animations: { () -> Void in
        UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.4, animations: { () -> Void in
            self.customView.backgroundColor = self.colors[1]
        })
        UIView.addKeyframeWithRelativeStartTime(0.4, relativeDuration: 0.8, animations: { () -> Void in
            self.customView.backgroundColor = self.colors[2]
        })
        UIView.addKeyframeWithRelativeStartTime(1.2, relativeDuration: 0.8, animations: { () -> Void in
            self.customView.backgroundColor = self.colors[3]
        })
        UIView.addKeyframeWithRelativeStartTime(2.0, relativeDuration: 0.8, animations: { () -> Void in
            self.customView.backgroundColor = self.colors[0]
        })
    }, completion: nil)

出于某种原因,它只是从颜色1跳到颜色0,并且根本不会变为颜色2和3。甚至在1和0之间的这种转换也是不同步的。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

你可以添加一个创建随机uicolors的函数。

func getRandomColor() -> UIColor{

        var randomRed:CGFloat = CGFloat(drand48())

        var randomGreen:CGFloat = CGFloat(drand48())

        var randomBlue:CGFloat = CGFloat(drand48())

        return UIColor(red: randomRed, green: randomGreen, blue: randomBlue, alpha: 1.0)

    }

并在你的func中使用它

func addPulsing() {
    println("Added")
    let pulsing = CAKeyframeAnimation(keyPath: "transform.scale")

    pulsing.duration = 0.8

    pulsing.values = [1.0,0.0,1.0]
    pulsing.keyTimes = [0.0,0.4,0.8]

    pulsing.removedOnCompletion = false
    pulsing.repeatCount = HUGE
    pulsing.calculationMode = kCAAnimationPaced

    //set background color
    customView.backgroundColor = getRandomColor()
    let layer = customView.layer
    layer.addAnimation(pulsing, forKey: "pulsing")
}

这是source

答案 1 :(得分:0)

好的,两个动画中的问题接近并且实际上我的方法中的问题实际上是我不知道/注意到关键帧中的相对时间是在0和1之间的间隔中指定的,因此它们是持续时间的分数,而我认为它们是事情发生的“确切”时间。结果,我使用两个动画并设置正确的时间解决了这个问题。

答案 2 :(得分:0)

这样做的一种方法是为每个循环重新创建动画,然后在每个动画之后设置视图的颜色。

// add the first animation
func firstAnimation() {
    let pulsing = CAKeyframeAnimation(keyPath: "transform.scale")
    pulsing.delegate = self

    pulsing.duration = 0.4
    pulsing.values = [1.0,0.0]
    pulsing.keyTimes = [0.0,1.0]

    pulsing.calculationMode = kCAAnimationPaced

    let layer = customView.layer
    layer.addAnimation(pulsing, forKey: "pulsing")
}

// continous pulsing animation constructor
func pulsingAnimation() -> CAAnimation {
    let pulsing = CAKeyframeAnimation(keyPath: "transform.scale")
    pulsing.delegate = self

    pulsing.duration = 0.8

    pulsing.values = [0.0,1.0,0.0] // invert the scale
    pulsing.keyTimes = [0.0,0.4,0.8]

    pulsing.calculationMode = kCAAnimationPaced
}

// then in the delegate, continue looping
func animationDidStop(_ theAnimation: CAAnimation!, finished flag: Bool) {
    customView.backgroundColor = // a new color
    customView.layer.addAnimation(pulsingAnimation(), forKey: "pulsing")
}