2013-06-30 30 views
5

我想模仿“想要”iPhone应用程序背景,有3种颜色我想让视图循环,让我们说红色,蓝色和绿色。如何在iOS上动画渐变动​​画

我想在那里有一个渐变,红色到蓝色到绿色,每个屏幕的三分之一,渐变为对方(渐变),然后,我想让红色离开屏幕顶部,并返回在底部。 (见下面的图片...)

动画应该向上移动,我想梯度上升,并在屏幕底部进行改造,然后往上走。

我尝试使用CAGradientLayer并为“颜色”属性设置动画效果,但看起来像是所有东西都相互淡入,不一定会从屏幕上移开。

考虑使用OpenGL,但不想为了看起来很简单的东西而做得那么低。任何帮助/代码示例将不胜感激。我基本上需要帮助动画使用CoreAnimation/CoreGraphics渐变。

在此先感谢!

enter image description here

enter image description here

enter image description here

回答

5

动画一个CAGradientLayer的colors属性只会导致褪色,因为你已经发现。不过,我认为一个渐变图层是要走的路。你应该看看以下选项:

  • 动画positions属性以及/而不是colors
  • 创建一个包含完整的动画周期较大的梯度层和动画的位置

第二个选项可能会提供最佳性能的梯度不会需要重新计算。

+0

好了,我试图创建一个梯度层大于屏幕(3×屏幕高度),和动画其position.y,它工作,直到position.y>屏幕origin.y 。我是否创建另一个渐变并将其放置在第一个渐变下面,以便它继续下去,在更大的渐变图层熄灭屏幕之后如何保持动画不变?我认为只需创建一个超长的CAGradientLayer,并将其位置设置为动画。并不一定是答案,因为它最终可能会结束。我希望它永远生动。 – Supereid86

+0

那么,当它到达一个循环点时,你会将位置重置到顶部(没有动画),然后再次循环。 – jrturton

+0

工作就像一个魅力。一个评论 - 我需要创建2个CAGradientLayers,一个红色蓝色红色,另一个红色蓝色红色。我把另一个放在另一个的上面(一个在顶部,一个在第一个的末尾开始),我激活了两个位置,直到第一个出现在屏幕上,第二个出现在第一个的起始位置。然后,我在没有动画的情况下将第一个动作移动到第二个动画,然后再次为position.y生成动画。谢谢@jrtuton! – Supereid86

0

你应该继承UIView类来创建一个GradientView类。添加一个数组来保存您正在移动的颜色。选择很重要,我解释了原因。覆盖的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开始和颜色阵列周围缠绕而因子是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() 
} 
+1

这似乎没有根据需要为渐变设置动画效果,我抬头看了一下你的speedo应用程序,并且动画非常漂亮,如果可能的话,你是如何实现的? – DrPatience

+1

我在一些伴侣代码的博客上添加了一篇文章,请看看,如果它是你想要的http://karmadust.com/animating-a-gradient-in-a-uiview/ –

+0

@MikeM该链接不再有效,你有另一个? –