如何在iOS上动画渐变动​​画

时间:2013-06-30 01:59:48

标签: iphone ios core-animation core-graphics

我想模仿“旺旺”的iPhone应用程序背景,有3种颜色我希望视图循环,让我们说红色,蓝色和绿色。

我希望有一个红色到蓝色到绿色的渐变,每个屏幕的1/3,相互褪色(渐变),然后,我希望红色从屏幕上移开并重新开始底部。 (见下面的照片......)

动画应该向上移动,我希望渐变上升并在屏幕底部进行改造然后向上移动。

我尝试使用CAGradientLayer并设置“colors”属性的动画,但这看起来就像所有内容相互淡化,不一定会移出屏幕。

考虑使用OpenGL,但不希望那些看似非常简单的东西。任何帮助/代码示例将非常感谢。我基本上需要使用CoreAnimation / CoreGraphics来帮助设置渐变动画。

提前致谢!

enter image description here

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:6)

正如您所发现的那样,

动画CAGradientLayer的colors属性只会导致淡入淡出。但是我觉得渐变层是要走的路。您应该查看以下选项:

  • 动画positions属性以及/而不是colors
  • 创建一个更大的渐变图层,其中包含完整的动画周期并为其位置设置动画

第二个选项可能会提供最佳性能,因为不需要重新计算渐变。

答案 1 :(得分:0)

您应该将UIView子类化以创建GradientView类。添加一个数组来保存您正在移动的颜色。选择很重要,我wrote an article解释了原因。覆盖 drawRect(rect:CGRect)方法并在颜色的组件之间进行插值:

override func drawRect(rect: CGRect) {

   let context = UIGraphicsGetCurrentContext();
   CGContextSaveGState(context);

   let c1 = colors[index == 0 ? (colors.count - 1) : index - 1] // previous
   let c2 = colors[index]                                       // current
   let c3 = colors[index == (colors.count - 1) ? 0 : index + 1] // next

   var c1Comp = CGColorGetComponents(c1.CGColor)
   var c2Comp = CGColorGetComponents(c2.CGColor)
   var c3Comp = CGColorGetComponents(c3.CGColor)

   var colorComponents = [
       c1Comp[0] * (1 - factor) + c2Comp[0] * factor, // color 1 and 2
       c1Comp[1] * (1 - factor) + c2Comp[1] * factor,
       c1Comp[2] * (1 - factor) + c2Comp[2] * factor,
       c1Comp[3] * (1 - factor) + c2Comp[3] * factor,
       c2Comp[0] * (1 - factor) + c3Comp[0] * factor, // color 2 and 3
       c2Comp[1] * (1 - factor) + c3Comp[1] * factor,
       c2Comp[2] * (1 - factor) + c3Comp[2] * factor,
       c2Comp[3] * (1 - factor) + c3Comp[3] * factor    
   ]

   let gradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), &colorComponents, [0.0, 1.0], 2)

   let startPoint = CGPoint(x: 0.0, y: 0.0)
   let endPoint = CGPoint(x: rect.size.width, y: rect.size.height)
   CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, CGGradientDrawingOptions.DrawsAfterEndLocation)

   CGContextRestoreGState(context);
}

索引变量从0开始并包围colors数组,而因子介于0.0和1.0之间并通过计时器动画:

var index: Int = 0
var factor: CGFloat = 1.0
var timer: NSTimer?

func animateToNextGradient() {
    index = (index + 1) % colors.count
    self.setNeedsDisplay()
    self.factor = 0.0    
    self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0/60.0, target: self, selector: "animate:", userInfo: nil, repeats: true)

}

func animate(timer: NSTimer) {
    self.factor += 0.02
    if(self.factor > 1.0) {
        self.timer?.invalidate()
    }
    self.setNeedsDisplay()
}