Je voudrais ajouter la réponse de n8gray que dans certains cas, vous devrez appeler setNeedsLayoutsuivi 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 contentViewpropriété et une edgeInsetspropriété qui permet de définir les marges autour du contentView. layoutSubviewsressemblerait à 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 edgeInsetspropriété, vous devez remplacer le edgeInsetssetter comme suit et appeler setNeedsLayoutsuivi 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.