2015-02-28 16 views
6

W moim app mam UIView korzystającą CALayer w celu osiągnięcia cień:Płynna animacja podczas ożywiania CALayer za shadowPath

@implementation MyUIView 

    - (instancetype) initWithFrame:(CGRect)frame { 
     self = [super initWithFrame:frame]; 
     if(!self) return self; 

     self.layer.shadowColor = [UIColor colorWithWhite:0 alpha:.2].CGColor; 
     self.layer.shadowOffset = CGSizeMake(0, 2); 
     self.layer.shadowOpacity = 1; 
     self.layer.shadowRadius = 1; 

     return self; 
    } 

@end 

Jeśli chcę coś zbliża rozsądną wydajność, muszę zdefiniować CALayer ' s shadowPath:

@implementation MyUIView 

    - (void) setFrame:(CGRect)frame { 
     [super setFrame:frame]; 

     self.layer.shadowPath = CGPathCreateWithRect(self.bounds, NULL); 
    } 

@end 

zauważyłem dwie rzeczy ilekroć animować tę UIView:

  1. Jeśli że nie użyć shadowPath, cień animuje wzdłuż ładnie obrotów i zmiany wielkości ramy. Zastrzeżenie tutaj to bardzo powolna animacja i ogólny brak wydajności.

  2. Jeśli zrobić zastosowanie shadowPath gdy UIView jest animowana animacji jest gładka i w odpowiednim czasie, jednak samo przejście cieniu jest znacznie bardziej blokowa (mniej gładka), niż to jest bez shadowPath.

Przykłady:

Edit:

Warto zauważyć, że te animacje są niejawne - Nie mówię im, powołując się. Są one wynikiem obracania się wraz z orientacją urządzenia w zakresie UIViewController. Cień znajduje się na UIView, który zmienia rozmiar podczas obrotu.

+0

Częścią problemu jest to, że podczas gdy ścieżki są animatable, nie mają _implicit_ animacje (te, które są wywoływane przez zmianę właściwości). Podczas obrotu ramka animuje się, ale ścieżka natychmiast zmienia swoją wartość końcową. –

+0

@ DavidRönnqvist Ah. To ma sens. Czy jest sposób na zrobienie tego ręcznie? – mattsven

+0

Tak, możesz ręcznie dodać animację. Ale jeśli nie uzyskasz takiego samego czasu i czasu trwania jak animacja klatek, nie będzie to wyglądało dobrze. –

Odpowiedz

4

Próbowałem odtworzyć zachowanie pokazane w dwóch dostarczonych przez ciebie gifach, ale bez powodzenia (może możesz edytować swoje pytanie za pomocą kodu animacji, np. UIView animateWithDuration:animations:).

Jednak gdzieś w głębi duszy pamiętam, że raz na jakiś czas spotkałem się z podobnym problemem i okazało się, że muszę rasteryzować widok, aby był sprawny.

Więc nie mogę zagwarantować, że to rozwiązuje problem dla ciebie, ale spróbować:

self.layer.shouldRasterize = YES; 
self.layer.rasterizationScale = [[UIScreen mainScreen] scale]; 
+0

Nie animuję ręcznie, to tylko kontroler widoku obracający się wraz z orientacją urządzenia. Wypróbuję twoją sugestię. – mattsven

+0

Witaj Dennis, to, oprócz * nie * używania 'shadowPath', rozwiązało to. To rozwiązuje problem wydajności, który normalnie nie powodowałby użycia 'shadowPath'. Dzięki! (Przyznam nagrodę za 7 godzinny czas) – mattsven

+0

Cieszę się, że pomogło! Dziękuję za przypomnienie, że obróciłeś urządzenie i że nie używasz 'shadowPath' w ostatecznej wersji. – Dennis

Powiązane problemy