2015-02-28 13 views
6

Nella mia app ho un UIView che sta utilizzando CALayer al fine di ottenere un'ombra:animazione liscia quando si anima shadowPath di un CALayer

@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 

Se voglio qualcosa che si avvicini prestazioni ragionevoli, devo definire il CALayer ' s shadowPath:

@implementation MyUIView 

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

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

@end 

ho notato due cose ogni volta che animare questo UIView:

  1. Se Non utilizzare un shadowPath, l'ombra anima la avanti bene con rotazioni e cambiamenti di formato telaio. L'avvertimento qui è un'animazione molto lenta e una generale mancanza di prestazioni.

  2. Se fare uso un shadowPath quando il UIView è animato l'animazione è liscia e tempestivo, comunque transizione dell'ombra stesso è molto più simili a blocchi (e meno liscia) che è senza shadowPath.

Esempi:

Edit:

Vale la pena notare che queste animazioni sono impliciti - non sto invocando io stesso. Sono il risultato della rotazione dello UIViewController con l'orientamento del dispositivo. L'ombra è su un UIView che modifica le dimensioni durante la rotazione.

+0

Parte del problema è che, mentre i percorsi sono animatable, non hanno _implicit_ animazioni (quelli che sono innescati da un cambiamento di proprietà). Quindi, durante la rotazione il frame si anima, ma il percorso cambia immediatamente al suo valore finale. –

+0

@ DavidRönnqvist Ah. Ciò ha senso. C'è un modo per farlo manualmente? – mattsven

+0

Sì, è possibile aggiungere manualmente un'animazione. Ma a meno che tu non abbia gli stessi tempi e durate dell'animazione del frame, non avrà un aspetto corretto. –

risposta

4

Ho provato a riprodurre il comportamento mostrato nei due gif forniti, ma senza esito positivo (forse è possibile modificare la domanda con il codice di animazione, ad esempio UIView animateWithDuration:animations:).

Tuttavia, da qualche parte nel retro della mia mente ricordo che ogni tanto ho riscontrato un problema simile, e ho scoperto che dovevo rasterizzare la vista per renderla fluida.

Quindi non posso garantire che si risolve il problema per voi, ma fare un tentativo:

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

Non sto animando manualmente, questo è solo un controller di visualizzazione che ruota con l'orientamento del dispositivo. Proverò il tuo suggerimento. – mattsven

+0

Ciao Dennis, questo, oltre a * not * utilizzando un 'shadowPath', lo ha risolto. Questo risolve il colpo di prestazioni che normalmente non si usa 'shadowPath'. Grazie! (Assegnerò la taglia quando il limite di 7 ore è scaduto) – mattsven

+0

Felice che sia stato d'aiuto! Grazie per aver segnalato che hai ruotato il dispositivo e che non usi 'shadowPath' nella versione finale. – Dennis

Problemi correlati