Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I would like to add on n8gray's answer that in some cases you will need to call <code>setNeedsLayout</code> followed by <code>layoutIfNeeded</code>.</p> <p>Let's say for example that you wrote a custom view extending UIView, in which the positioning of subviews is complex and cannot be done with autoresizingMask or iOS6 AutoLayout. The custom positioning can be done by overriding <code>layoutSubviews</code>.</p> <p>As an example, let's say that you have a custom view that has a <code>contentView</code> property and an <code>edgeInsets</code> property that allows to set the margins around the contentView. <code>layoutSubviews</code> would look like this:</p> <pre><code>- (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); } </code></pre> <p>If you want to be able to animate the frame change whenever you change the <code>edgeInsets</code> property, you need to override the <code>edgeInsets</code> setter as follows and call <code>setNeedsLayout</code> followed by <code>layoutIfNeeded</code>:</p> <pre><code>- (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 } </code></pre> <p>That way, if you do the following, if you change the edgeInsets property inside an animation block, the frame change of the contentView will be animated.</p> <pre><code>[UIView animateWithDuration:2 animations:^{ customView.edgeInsets = UIEdgeInsetsMake(45, 17, 18, 34); }]; </code></pre> <p>If you do not add the call to layoutIfNeeded in the setEdgeInsets method, the animation won't work because the layoutSubviews will get called at the next update cycle, which equates to calling it outside of the animation block.</p> <p>If you only call layoutIfNeeded in the setEdgeInsets method, nothing will happen as the setNeedsLayout flag is not set.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload