2011-01-20 10 views
22

Tutti e ogni libro afferma che ci sono animazioni implicite che si verificano in CALayer. Tuttavia, ogni volta che volevo verificarlo fino a quel momento, finivo con un hard-snap sul valore impostato. Nessuna animazione.Quando esattamente le animazioni implicite avvengono in iOS?

Ecco un esempio in un progetto in cui non accade nient'altro. Tutto ciò che faccio è creare una vista, quindi ottenere l'istanza di CALayer e fare qualcosa che dovrebbe essere animato implicitamente.

[theLayer setValue:[NSNumber numberWithFloat:M_PI * 1.1] forKeyPath:@"transform.rotation.z"]; 

Un altro:

CGRect currentBounds = theLayer.bounds; 
currentBounds.size.width += 120.f; 
[self.animatedLayer setBounds:currentBounds]; 

la vista contiene alcune cose, naturalmente, in modo da poter vedere il cambiamento. Vedo il cambiamento visivo, ma come uno scatto difficile. Nessuna animazione.

Quindi tutti questi libri sono errati e hanno in mente le vecchie conoscenze di Mac OS X quando si scrive su Animazione di base e animazioni implicite, o sto facendo qualcosa di sbagliato. Qualcuno può fornire un esempio funzionante che mostri animazioni implicite su iPhone?

risposta

65

UIKit disabilita le animazioni implicite. Per essere più specifici, un CALayer associato a un UIView non si animerà mai implicitamente. I CALayer creati da te e che non sono associati a un UIView acquisteranno il normale meccanismo di animazione implicito.

Se sei interessato a come funziona, le animazioni implicite avvengono dopo il normale -actionForKey: lookup. Se esiste una CAAction per una determinata proprietà, viene utilizzata. Altrimenti, viene utilizzata l'animazione implicita. Nel caso di un CALayer associato a un UIView, UIView implementa il metodo delegato -actionForLayer:forKey: e quando non si trova in un blocco di animazione UIView restituisce sempre [NSNull null] per indicare che la ricerca dell'azione dovrebbe terminare qui. Ciò impedisce il funzionamento delle animazioni implicite. All'interno di un blocco di animazione UIView, costruisce la propria azione per rappresentare le impostazioni di animazione di UIView correnti. Di nuovo, questo impedisce le animazioni implicite.

Se è necessario animare le proprietà CALayer che UIView non farà per voi, è possibile utilizzare una sottoclasse CAAnimation esplicita (come CABasicAnimation).

+1

Ottima risposta! Sono curioso - dove hai ottenuto tutte queste informazioni dettagliate? Ho controllato così tanti libri e fonti ma mancano di questi dettagli. –

+0

Principalmente tentativi ed errori. Se si esegue l'override di '-actionForLayer: forKey:' in una sottoclasse di UIView è possibile disconnettere i risultati della chiamata a super e correlarli con l'eventuale presenza di un blocco di animazione attivo. Ha senso anche se ci pensate - l'UIView è il delegato del CALayer, e '-actionForLayer: forKey:' è il posto giusto dove connettersi se si desidera disabilitare le animazioni implicite. –

+0

Ha molto senso. Grazie! –

0

È inoltre possibile impostare il delegato del livello sul proprio oggetto e gestire -actionForLayer: forKey :. Sembra che si ottenga un'animazione implicita anche se il delegato non implementa -actionForLayer: forKey :.

2

Vecchio post, ma il collegamento sotto punta a una sezione della Guida alla programmazione dell'animazione core che aiuta a far luce su ciò che Kevin Ballard stava dicendo. C'è davvero bisogno di una nota sfacciata che menzioni il fatto che per animare le proprietà del layer sottostante di un UIView è necessario assicurarsi di impostare il delegato del livello su un'istanza che adotterà il metodo "actionForLayer: ForKey:" e restituirà nil. È stato trovato che puoi anche impostare il delegato su un'istanza che non adotta questo metodo e che consente comunque animazioni implicite, ma questa è una pratica sciatta e confusa.

Core Animation - Layer Actions - Defined Search Pattern for Action Keys

1

Tenete a mente che sottolivelli dello strato primario di un UIView normalmente non hanno l'UIView come loro delegato. Pertanto, partecipano all'animazione implicita a meno che non lo blocchi esplicitamente, anche se non hai fornito un delegato per restituire un'azione nil in risposta a actionForLayer: forKey :.

Quindi, un modo semplice per ottenere un'animazione implicita in una vista generica è semplicemente aggiungere un sottolivello che copra il livello principale.

Il libro di Matt Neuberg Programmazione iOS 5 (attualmente in beta su Safari Books Online) spiega molto chiaramente questo argomento.

1

È esattamente corretto della risposta di Kevin Ballard. Voglio fornire qualcosa di più qui.

Le informazioni di dettaglio dal official document

c'è una sezione chiamata: regole per modificare i livelli in iOS, e troverete

La classe UIView disabilita le animazioni di livello di default, ma li riattiva all'interno animazione blocchi.

Tranne abilitare l'implicito nel blocco di animazione UIView. Ci sono altre due soluzioni:

  1. Rendi il livello di cui hai bisogno l'animazione come sottostrato di una vista. Fare riferimento alla [risposta] [2]

    [2]: Implicit property animations do not work with CAReplicatorLayer? di fade-in di animazione implicita non funziona. Ho provato questo, ha funzionato come previsto.

  2. assegnare il delegato del livello al livello stesso. Il delegato di default del layer in iOS è la sua vista del backing store che implementa il parametro actionForLayer: (id) forKey: (NSString *) e restituisce [NSNull null] per disabilitare l'animazione implicita del livello.
0

in realtà, si potrebbe solo restituire nil per ottenere l'animazione predefinita di CALay.

  • (id) actionForLayer: (CALayer *) strato Forkey: (NSString *) evento { ritorno pari a zero; }
+0

/* Se definito, chiamato dall'implementazione predefinita di * -actionForKey: metodo. Dovrebbe restituire un oggetto che implementa il protocollo * CAAction. Può restituire 'nil' se il delegato non specifica * un comportamento per l'evento corrente.Restituire l'oggetto nullo (ad esempio * '[NSNull null]') non forza esplicitamente alcuna ulteriore ricerca. (I.e * + defaultActionForKey: il metodo non verrà chiamato.) * / – dongxin

Problemi correlati