2009-02-05 11 views
33

Próbuję skonstruować animację CABasic, aby animować właściwość backgroundColor obiektu Core Animation CALayer, ale nie wiem, jak prawidłowo zawinąć wartość CGColorRef, aby przekazać animację. Na przykład:W jaki sposób jawnie animujesz kolor tła CALayer?

CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB(); 
CGFloat values[4] = {1.0, 0.0, 0.0, 1.0}; 
CGColorRef red = CGColorCreate(rgbColorspace, values); 
CGColorSpaceRelease(rgbColorspace); 

CABasicAnimation *selectionAnimation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"]; 
[selectionAnimation setDuration:0.5f]; 
[selectionAnimation setToValue:[NSValue valueWithPointer:red]]; 
[layer addAnimation:selectionAnimation forKey:@"selectionAnimation"]; 

wydaje się zrobić nic do nieruchomości backgroundColor, zakładam, ponieważ przekazanie go jako wskaźnik zawinięte w NSValue nie jest sposób przekazać ją wzdłuż.

backgroundColor to animowalna własność CALayera, więc moje pytanie brzmi: jak ustawić wartości From lub To dla tej konkretnej właściwości (najlepiej w niezależny od platformy Mac/iPhone sposób)?

Odpowiedz

57

Nie trzeba zawijać CGColorRef s przy ustalaniu toValue lub fromValue właściwości CABasicAnimation. Po prostu użyj CGColorRef. Aby uniknąć ostrzeżenia kompilatora, możesz rzucić CGColorRef na id.

W mojej przykładowej aplikacji poniższy kod animował tło na czerwono.

CABasicAnimation* selectionAnimation = [CABasicAnimation 
    animationWithKeyPath:@"backgroundColor"]; 
selectionAnimation.toValue = (id)[UIColor redColor].CGColor; 
[self.view.layer addAnimation:selectionAnimation 
         forKey:@"selectionAnimation"]; 

Po zakończeniu animacji tło powraca do oryginalnego koloru. Dzieje się tak, ponieważ CABasicAnimation wpływa tylko na warstwę prezentacji warstwy docelowej podczas działania animacji. Po zakończeniu animacji zostanie zwrócona wartość ustawiona w warstwie modelu. Będziesz więc musiał również ustawić właściwość layer backgroundColor na czerwony. Być może wyłączyć niejawne animacje za pomocą CATransaction.

Możesz uratować się z tego problemu, korzystając przede wszystkim z niejawnej animacji.

+13

Słodki. Można by pomyśleć, że gdzieś dokumentują typecast na id. Tak, mógłbym ułatwić sobie życie dzięki niejawnej animacji, ale to mnie wkurzyło. Aby to się udało, wystarczy ustawić właściwość fillMode animacji na kCAFillModeForwards i removedOnCompletion na NIE. –

+0

+1 Miło, działa jak urok! –

+0

Możesz też zaoszczędzić mnóstwo czasu i skorzystać z biblioteki Pop na Facebooku: https://github.com/facebook/pop. Przykłady tutaj: https://github.com/maxmyers/FacebookPop – Benjamin

2

Walczyłem z tym problemem, dopóki nie eksperymentalnie nie znalazłem blokady. Ustawienie właściwości backgroundColor warstwy, bezpośrednio lub za pośrednictwem animacji, nie przyniesie efektu, jeśli zmienisz kolor tła z domyślnego (nieokreślonego) w Konstruktorze interfejsu, w kontekście oczywiście elementu (takiego jak UILabel), który jest zostały umieszczone w IB. Pozostaw więc kolor tła nieokreślony, a powyższe powinno zadziałać.