2013-03-23 12 views
7

Sto cercando di fare una "traduzione" esatta di questa UIView codice di animazione basata su blocchi:Animate utilizzando CABasicAnimation

[UIView animateWithDuration:0.5 
         delay:0.0 
        options:UIViewAnimationOptionCurveEaseInOut 
       animations:^{ 
           someView.frame = CGRect(0, 100, 200, 200); 
          } 
       completion:nil]; 

utilizzando CABasicAnimation invece.

Sono totalmente consapevole che la proprietà telaio è in realtà una combinazione di posizione, limiti e AnchorPoint dello strato sottostante, come è descritto qui: http://developer.apple.com/library/mac/#qa/qa1620/_index.html
... e ho già fatto una soluzione del genere, utilizzando due CABasicAnimations una impostazione la posizione, una per limiti e funziona per quella vista.

Il problema è comunque che ho sotto-visualizzazione nella mia vista. someView ha una sottoview di tipo UIScrollView in cui metto ancora un'altra sottocategoria di tipo UIImageView. La sottoview UIScrollView ha autoresizingMask impostato su UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight. Tutto funziona perfettamente se utilizzo la versione basata su blocco UIView, tuttavia quando provo a utilizzare CABasicAnimations le sottoview iniziano a comportarsi in modo imprevisto (cioè vengono ridimensionate a larghezze errate). Quindi sembra che autoresizingMask non funzioni correttamente quando si utilizza CABasicAnimations. Ho notato anche che le sottoview non ricevono una chiamata a setFrame:, sebbene la proprietà frame della vista genitore cambi dopo che le modifiche alla posizione del layer e ai limiti sono stati apportati.

Ecco perché mi piacerebbe sapere quale sarebbe il codice corretto di replicare con CABasicAnimation che ciò che sta accadendo quando si usa animateWithDuration metodo UIView.

risposta

11

Sono totalmente consapevole che la proprietà telaio è in realtà una combinazione di posizione, limiti e AnchorPoint dello strato sottostante

buone, ma è importante anche essere consapevoli che frame non è un animatable proprietà per strati. Se si desidera animare con CABasicAnimation, è necessario utilizzare proprietà animabili per i livelli. La documentazione del CALayer contrassegna ogni proprietà come esplicitamente "animabile". L'idea di utilizzare bounds e position è corretta.

Così, questo codice fa in sostanza quello che stavi facendo prima:

[CATransaction setDisableActions:YES]; 
// set final bounds and position 
v.layer.bounds = CGRectMake(0,0,200,200); 
v.layer.position = CGPointMake(100,200); 

// cause those changes to be animated 
CABasicAnimation* a1 = [CABasicAnimation animationWithKeyPath:@"bounds"]; 
a1.duration = 0.5; 
CABasicAnimation* a2 = [CABasicAnimation animationWithKeyPath:@"position"]; 
a2.duration = 0.5; 
[v.layer addAnimation:a1 forKey:nil]; 
[v.layer addAnimation:a2 forKey:nil]; 

tuttavia, che il codice non ha alcun effetto sulle dimensioni di eventuali sottolivelli di v.layer. (Una sottoview di v viene disegnata da un sottolivello di v.layer). Questo, purtroppo, è il problema che stai cercando di risolvere. Credo che abbassando il livello degli strati e dirigendo l'animazione core esplicita, hai rinunciato all'autorizing, che avviene a livello di vista.Quindi avrai bisogno di animare anche i sottolivelli. Questo è ciò che l'animazione della vista stava facendo per te.

Questa è una sfortunata caratteristica di iOS. Mac OS X ha dei vincoli di livello (CAConstraint) che eseguono a livello di livello ciò che autorizza a livello di vista (e altro). Ma iOS manca questa funzionalità.

+0

Sì, ho creato due CABasicAnimations uno per @ "position" KeyPath, l'altro per @ "bounds". Ho impostato i valori individuali da Valore e Valore. Poi ho creato un CAAnimationGroup e aggiunto queste due animazioni, dopo di che aggiungo l'animazione di gruppo al livello. Alla fine ho impostato someView.layer.bounds e someView.layer.position sui nuovi valori desiderati (usati in toValue) in modo che la modifica persista effettivamente nell'albero del livello del modello. –

+0

L'animazione funziona con someView, che è una vista principale (principale) contenente altre visualizzazioni secondarie. Il problema è che le sottoview non vengono ridimensionate, mantengono la loro larghezza come se ci fosse un problema con autoresizingMask (che è impostato su di esse). Funziona tutto quando si usa UIView animateWithDuration: comunque vorrei usare CABasicAnimations poiché ho bisogno di opzioni di configurazione aggiuntive ... –

+2

Sono con voi. Credo che poiché stai animando direttamente il livello, dovrai gestire manualmente anche l'animazione dei sottolivelli. – matt