Je voudrais ajouter la réponse de n8gray que dans certains cas, vous devrez appeler setNeedsLayout
suivi de layoutIfNeeded
.
Disons par exemple que vous avez écrit une vue personnalisée étendant UIView, dans laquelle le positionnement des sous-vues est complexe et ne peut pas être fait avec autoresizingMask ou iOS6 AutoLayout. Le positionnement personnalisé peut être effectué par substitution layoutSubviews
.
À titre d'exemple, disons que vous avez une vue personnalisée qui a une contentView
propriété et une edgeInsets
propriété qui permet de définir les marges autour du contentView. layoutSubviews
ressemblerait à ceci:
- (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);
}
Si vous souhaitez pouvoir animer le changement de cadre chaque fois que vous modifiez la edgeInsets
propriété, vous devez remplacer le edgeInsets
setter comme suit et appeler setNeedsLayout
suivi de 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
}
De cette façon, si vous procédez comme suit, si vous modifiez la propriété edgeInsets à l'intérieur d'un bloc d'animation, le changement d'image de contentView sera animé.
[UIView animateWithDuration:2 animations:^{
customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34);
}];
Si vous n'ajoutez pas l'appel à layoutIfNeeded dans la méthode setEdgeInsets, l'animation ne fonctionnera pas car la layoutSubviews sera appelée au prochain cycle de mise à jour, ce qui revient à l'appeler en dehors du bloc d'animation.
Si vous appelez uniquement layoutIfNeeded dans la méthode setEdgeInsets, rien ne se passera car l'indicateur setNeedsLayout n'est pas défini.