Domanda

Ho una UIView con un mazzo di subviews, tutti posizionati utilizzando layoutSubviews. Quando il view viene ridimensionato, le posizioni relative tutti i cambiamenti. Mi piacerebbe queste ri-calcoli per accadere nel corso di un ridimensionamento animato (usando + chiamate [UIView beginAnimations:]). Questo non sembra accadere. Tutte le idee?

È stato utile?

Soluzione

Ipotesi: Volete avere più passaggi di animazione (vale a dire la posizione non cambia linearmente con dimensioni del fotogramma)

.

Questo non è possibile con un singolo animazioni UIView "standard". Perché? Il telaio / limiti occupa solo una volta.

core Animation dispone di tre "alberi di strato":

  • Il modello ad albero è dove la vostra applicazione pensa che le cose sono.
  • Il presentazione albero è di circa ciò che viene visualizzato sullo schermo.
  • Il il rendering albero è di circa ciò Core Animation è compositing.

UIView è una (un po 'sottile) wrapper il livello di modello. Durante un'animazione UIView, Core Animation aggiorna la presentazione / rendere albero - l'albero modello rappresenta il punto finale di animazioni. Il risultato è che il codice può (per la maggior parte) le animazioni trattare come istantanea - lo spostamento di una vista da A a B si muove istantaneamente a B; il cambiamento avviene solo per essere animato per l'utente.

Ci sono cose più complicate si possono fare con CALayer / CAAnimation direttamente, ma non ho studiato così tanto.

Si potrebbe a catena più animazioni insieme utilizzando - [UIView setAnimationDidStopSelector:]. (Si potrebbe anche provare a utilizzare più animazioni con setAnimationDelay :, ma non sono sicuro di quello che succede con animazioni multiple sulla stessa proprietà, si potrebbe avere fortuna con setAnimationBeginsFromCurrentState:.)

Se si vuole il controllo veramente a grana fine, CADisplayLink (OS 3.1+) è un timer che gli incendi dopo ogni aggiornamento dello schermo. Un'opzione di riserva (per 3.0 il supporto) è quello di utilizzare un NSTimer a 30/60 Hz o giù di lì.

Altri suggerimenti

Completamento @ Anwer di GrizzlyNetch, è possibile impostare l'opzione UIViewAnimationOptionLayoutSubviews di animazione, quindi non c'è bisogno di chiamata layoutIfNeeded:

-(void)someMethod{
    double duration = ...;
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        self.frame = ...;
    } completion:nil];
}

So che questa è una vecchia questione, ma questo codice funziona per me molto bene (adatto per il tuo esempio di cambiare telaio).

-(void)layoutSubviews{
     [super layoutSubviews];
     // layout your subviews here, or whatever
}

-(void)someMethod{
    double duration=...;
    [UIView animateWithDuration:duration animations:^{
        self.frame = ...;
        [self layoutIfNeeded];
    }];
}

Naturalmente è possibile chiamare questo metodo da un altro oggetto. Il "trucco" è quello di chiamare layoutIfNeeded (o layoutSubviews direttamente - stessa cosa, se si cambia la cornice del setNeedsLayout si chiama).

Come tc. ben spiegato gli "alberi di livello", Basta forzare il livello di presentazione per visualizzare la fase finale di strato del modello con l'animazione.

Il vantaggio di questo metodo è la possibilità di controllare quando il telaio / delimita cambiamento è animata e quando è immediata.

Spero che questo aiuti qualcuno:.)

distacco per completezza. Grazie a TC. per spiegare che ciò che voglio fare, esattamente, non è supportato da Core Animation.

Alla fine ho si avvicinò con una soluzione ragionevole. Piuttosto che il layout miei subviews in -layoutSubviews, lo faccio in -setBounds :. Poi, quando ho avvolgere un -setBounds: chiamata in un UIView + beginAnimations: blocco, quelle chiamate di posizionamento sono anche animati, e il risultato finale è tutto correttamente l'animazione a dove dovrebbe dio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top