2013-06-30 15 views
5

Chcę naśladować tło aplikacji "Chcę" w telefonie iPhone, są 3 kolory, które chcę, aby przeglądał cykl, powiedzmy czerwony, niebieski i zielony.Jak animować gradient przesuwając się w górę na iOS

Chcę, aby był gradient od czerwonego do niebieskiego do zielonego, każde 1/3 ekranu, wyblakłe do siebie (gradient), a następnie chcę, aby czerwony wyszedł z ekranu na górze i wrócił na dole. (Zobacz zdjęcia poniżej ...)

Animacja powinna przesunąć się w górę, chcę, aby gradient wzrósł i przeprowadzić reformowanie u dołu ekranu i przejść w górę.

Próbowałem używać CAGradientLayer i animować właściwość "colors", ale wygląda na to, że wszystko zlewa się ze sobą, niekoniecznie zsuwając się z ekranu.

Kontemplowanie za pomocą OpenGL, ale nie chcę iść tak nisko na coś, co wydaje się dość proste. Wszelkie próbki pomocy/kodu byłyby bardzo doceniane. Zasadniczo potrzebuję pomocy w animowaniu gradientu za pomocą CoreAnimation/CoreGraphics.

Z góry dziękuję!

enter image description here

enter image description here

enter image description here

Odpowiedz

5

Animowanie właściwość CAGradientLayer colors będzie tylko powodować blaknięcie, jak odkryliśmy. Myślę jednak, że warstwa gradientowa jest drogą do zrobienia. Należy spojrzeć na następujących opcji:

  • animowanie właściwości positions a także/zamiast colors.
  • tworząc większą warstwę gradientu, który zawiera pełny cykl animacji i animacji swoją pozycję

Druga opcja będzie prawdopodobnie daje najlepszą wydajność jako gradient nie będzie musiała zostać ponownie obliczona.

+0

Ok, że próbował tworząc warstwę gradientu większy niż ekran (3 x wysokość ekranu), a jej animowanych position.y i działa aż do position.y> origin.y ekranu . Czy mogę utworzyć inny gradient i umieścić go pod pierwszym, aby był kontynuowany, w jaki sposób utrzymujesz animację po tym, jak większa warstwa gradientu zniknie z ekranu? Myślę, że stworzenie warstwy CAGradientLayer z bardzo dużą wysokością i animacją jej pozycji nie jest koniecznie odpowiedzią, ponieważ wciąż może się w końcu skończyć. Chciałbym, aby animowało się na zawsze. – Supereid86

+0

Cóż, gdy dojdzie do punktu pętli, możesz zresetować pozycję do góry (bez animacji), a następnie ponownie pętli. – jrturton

+0

Pracował jak urok. Jedna uwaga - musiałem stworzyć dwie warstwy CAGradientayers, jedną czerwono-niebiesko-czerwoną i drugą czerwono-niebiesko-czerwoną.Położyłem jeden na drugim (jeden na górze i jeden zaczynając na końcu pierwszego), animowałem pozycję.y obu, dopóki pierwszy nie zniknął z ekranu, a drugi był teraz u początku pierwszego. Następnie przeniosłem pierwszą pod drugą bez animacji i ponownie animowałem pozycję. Dzięki @jrtuton! – Supereid86

0

Powinieneś utworzyć podklasę UIView, aby utworzyć klasę GradientView. Dodaj tablicę do przechowywania kolorów, przez które przechodzisz. Wybór jest ważny i I wrote an article wyjaśnia, dlaczego. Zastąpić drawRect (rect: CGRect) sposób i interpolacji pomiędzy składnikami kolorów:

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); 
} 

Zmienny indeks zaczyna się od 0 i otacza tablicy kolorów, gdy współczynnik wynosi 0,0 do 1,0, a animację przez zegar:

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

Wygląda na to, że animacja gradientu nie jest wymagana. Sprawdziłem aplikację Speedo i animacja jest znakomita, jak udało Ci się to osiągnąć, jeśli mogę? – DrPatience

+1

Dodałem post po twoim pytaniu na moim blogu z dodatkowym kodem towarzyszącym. Proszę sprawdzić, czy tego właśnie chcesz http://karmadust.com/animating-a-gradient-in-a-uiview/ –

+0

@MikeM Ten link już nie działa, czy masz inny? –