Je tiens à ajouter sur n8gray de répondre que, dans certains cas, vous aurez besoin de faire appel setNeedsLayout
suivie par layoutIfNeeded
.
Par exemple, disons que vous avez écrit une vue personnalisée de l'extension de UIView, dans lequel le positionnement des sous-vues est complexe et ne peut être fait avec autoresizingMask ou iOS6 mise en page automatique. La coutume de positionnement peut être réalisé en remplaçant layoutSubviews
.
Comme un exemple, disons que vous avez une vue personnalisée qui a un contentView
de la propriété et un edgeInsets
propriété qui permet de définir les marges autour de la 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 voulez être capable d'animer l'image changent chaque fois que vous modifiez l' edgeInsets
de la propriété, vous devez remplacer la edgeInsets
setter comme suit et appelez - setNeedsLayout
suivie par 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 faites ce qui suit, si vous modifiez le edgeInsets de la propriété à l'intérieur d'un bloc d'animation, le cadre, le changement de la contentView seront animées.
[UIView animateWithDuration:2 animations:^{
customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34);
}];
Si vous n'ajoutez pas l'appel à layoutIfNeeded dans le setEdgeInsets méthode, l'animation ne fonctionne pas car la layoutSubviews sera appelée lors du prochain cycle de mise à jour, ce qui équivaut à appeler à l'extérieur du bloc d'animation.
Si vous n'appelez layoutIfNeeded dans le setEdgeInsets méthode, rien ne se passera comme la setNeedsLayout indicateur n'est pas défini.