Vorrei aggiungere la risposta di n8gray che in alcuni casi dovrai chiamare setNeedsLayout
seguito da layoutIfNeeded
.
Supponiamo ad esempio che tu abbia scritto una visualizzazione personalizzata che estende UIView, in cui il posizionamento delle sottoview è complesso e non può essere eseguito con autoresizeMask o iOS6 AutoLayout. Il posizionamento personalizzato può essere eseguito sovrascrivendo layoutSubviews
.
Ad esempio, supponiamo di avere una visualizzazione personalizzata che ha una contentView
proprietà e una edgeInsets
proprietà che consente di impostare i margini attorno a contentView. layoutSubviews
sarebbe simile a questo:
- (void) layoutSubviews {
self.contentView.frame = CGRectMake(
self.bounds.origin.x + self.edgeInsets.left,
self.bounds.origin.y + self.edgeInsets.top,
self.bounds.size.width - self.edgeInsets.left - self.edgeInsets.right,
self.bounds.size.height - self.edgeInsets.top - self.edgeInsets.bottom);
}
Se vuoi essere in grado di animare il cambio di frame ogni volta che cambi la edgeInsets
proprietà, devi sovrascrivere il edgeInsets
setter come segue e chiamare setNeedsLayout
seguito da layoutIfNeeded
:
- (void) setEdgeInsets:(UIEdgeInsets)edgeInsets {
_edgeInsets = edgeInsets;
[self setNeedsLayout]; //Indicates that the view needs to be laid out
//at next update or at next call of layoutIfNeeded,
//whichever comes first
[self layoutIfNeeded]; //Calls layoutSubviews if flag is set
}
In questo modo, se si esegue quanto segue, se si modifica la proprietà edgeInsets all'interno di un blocco di animazione, il cambio di frame di contentView verrà animato.
[UIView animateWithDuration:2 animations:^{
customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34);
}];
Se non aggiungi la chiamata a layoutIfNeeded nel metodo setEdgeInsets, l'animazione non funzionerà perché layoutSubviews verrà chiamato al successivo ciclo di aggiornamento, il che equivale a chiamarlo al di fuori del blocco dell'animazione.
Se chiami solo layoutIfNeeded nel metodo setEdgeInsets, non accadrà nulla poiché il flag setNeedsLayout non è impostato.