2012-04-03 12 views
27

Robię więc niestandardowe animacje na moim kontrolerze nawigacji oraz sposób, w jaki popycha i wyświetla kontrolery viewController.CALayer - Shadow powoduje trafienie wydajności?

Wszystko działa płynnie. Jak tylko dodam następujący kod (w podklasie UINavigationController), mam do czynienia z ogromnym hitem wydajności. Po dodaniu cienia wszystkie animacje stają się bardzo opóźnione. Czy to jest oczekiwane, czy też robię coś nie tak w kodzie?

// This code gets called once during NavigationController initialization. 
[self.view setClipsToBounds:NO]; 
[self.view.layer setCornerRadius:5]; 
[self.view.layer setShadowOffset:CGSizeMake(0, 20)]; 
[self.view.layer setShadowColor:[[UIColor yellowColor] CGColor]]; 
[self.view.layer setShadowRadius:20.0]; 
[self.view.layer setShadowOpacity:1]; 

EDIT:

Zmieniono mój promień cień do 1 i jest nadal powolny

+0

Dla wszystkich, że warto, to jest pokryte wyraźnie w WWDC 2010 Session 425: Rdzeń Animacja w praktyce, część 2 (https://developer.apple [tutaj]. .com/devcenter/download.action? ścieżka =/videos/wwdc_2010__sd/session_426__core_image_effects_and_optimization.mov) –

Odpowiedz

39

Powinieneś oczekiwać spowolnienia od dodawania cienia. shadowRadius z 20 jest bardzo wysokie i będzie szczególnie wolne.

Inny klucz do poprawy szybkości renderowania w tle: ustaw właściwość shadowPath. To może pomóc radykalnie.

+0

ustawienie ShadowPath zmyślił, Mój promień cienia wynosi 10 i nadal działa dobrze. – aryaxt

+0

właśnie uratowałem moje życie :) –

+2

@NicolasManzini Więcej porad dotyczących wydajności cienia: http://stackoverflow.com/questions/10133109/fastest-way-to-do-shadows-on-on-ios/10133182#10133182 – aryaxt

2

Tak, cień są bardzo drogie (zwłaszcza cień tak duży - grać z promieniem i ty” Zauważ, że to robi ogromną różnicę w stopniu spowolnienia, którego doświadczasz). Jednym ze sposobów poprawy wydajności jest renderowanie go raz do CGImageContext i wyświetlanie tego obrazu zamiast ponownego renderowania warstwy za każdym razem, gdy jest ona przerysowana (ale to nie działa, jeśli cień potrzebuje animacji lub coś takiego).

+0

Myślisz, że lepiej byłoby użyć rzeczywistego png i dodać go do mojego UIView? – aryaxt

+0

Jeśli jest to możliwe (tzn. Znasz kształt/rozmiar/cokolwiek z wcześniejszego cienia), to zdecydowanie da ci lepszą wydajność. Blitting zdjęć jest znacznie szybszy niż renderowanie cieni. –

+0

Prerendered do obrazu będzie działać tak długo, jak długo nie będziesz musiał zmieniać kształtu cienia. –

79
self.view.layer.shouldRasterize = YES; 
self.view.layer.rasterizationScale = UIScreen.mainScreen.scale; 

Byłem niedawno mając pewne problemy z powolnych cieni CALayer, a prosta linia kodu stała się dla mnie wszystko!

+0

niesamowite, dzięki czemu działa jeszcze lepiej, teraz mogę mieć dowolny rozmiar shadowRadius bez uderzenia wydajności – aryaxt

+21

To zignoruje obrazy siatkówki, które możesz mieć dla ciebie adnotacji. Aby to naprawić, dodaj następującą linię: self.view.layer.rasterizationScale = [UIScreen mainScreen].skala; – Sean

+2

Mam podobny problem z tableView, gdzie każda komórka zawiera kilka UILabels, a także widok z zaokrąglonymi narożnikami. Dodałem cień do warstwy, która zawiera tableView, a przewijanie staje się niestabilne. Jednak ustawienie shouldRasterize = YES rozwiązało chropowatość, ale pikselowało widok (wyraźnie rozmyte), więc nie jest to dopuszczalne rozwiązanie. Znalazłem użycie shadowPath zamiast shadowOffset. –

13

Używanie shadowPath zamiast shadowOffset.

theView.layer.shadowPath = [UIBezierPath bezierPathWithRect:theView.bounds].CGPath; 

Sprawdź ten post: iphone - Animation's performance is very poor when view's shadow is on

+0

Pracował jak zaklęcie, lepiej niż powinienRasteryzować, który zamazał widok i wszystkie podwarstwy. –

+1

Jest to bardzo skuteczny sposób, w jaki testuję ... Pomysł z RadeRasterize nie jest tak szybki, jak może być potrzebny. ta odpowiedź jest znacznie lepsza! nie rozumiem, dlaczego odpowiedź @williamcotton zyskuje tyle głosów ... –

+0

shadowPath jest całkiem niezły i szybki, ale jak można zachować ramkę aktualizacji w autolayout? – TomSawyer