2013-06-30 64 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該鏈接不再有效,你有另一個? –