1

I looked into http://developer.apple.com/library/ios/#recipes/xcode_help-interface_builder/articles/UnderstandingAutolayout.html but the explanations are pretty vague.

I'm on iOS 6. I have a view controller with two child views, one on top of another:

viewcontroller layout

I want to use autolayout to set up the views in such way that if I change the top view's frame programatically, the bottom view will resize to accommodate the top view's new frame. That is, if I increase the top view's height, the bottom view's height should drecrease to keep the same separation between both views; the opposite should happen if I decrease the top view's height.

The default constraints I get for these two views in Xcode are:

tableview constraints

mapview constraints

And if I hold Command and resize the top (map) view, the bottom (tableview) seems to correctly shrink or expand vertically to honor the space constraint between them.

However, the minute I try modifying the top view's frame or bounds via code, for instance:

self.topView.frame = CGRectMake(0, 0, 320, 514);

The bottom view doesn't shrink. So what am I missing?

SaldaVonSchwartz
  • 3,769
  • 2
  • 41
  • 78

1 Answers1

4

You can't modify self.topView.frame like that. Setting the frame is auto layout's job. You need to modify the constraints and then let auto layout update the frame.

Create an outlet of type NSLayoutConstraint in your view controller:

@property (nonatomic, strong) IBOutlet NSLayoutConstraint *topViewHeightConstraint;

Connect the outlet to the height=127 constraint on the top view in your storyboard. See this answer if you need more help connecting an outlet to the constraint.

Then, to change the height of the top view, and have auto layout update the frame of the bottom view too, set the constraint's constant:

self.topViewHeightConstraint.constant = 514;

At the end of the run loop (not right away, but before the screen is updated), auto layout will modify the frames of both views to satisfy the changed constraint.

Community
  • 1
  • 1
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • oh ok, I get it. I thought they worked the other way around: a change in frame triggering a change in constraint. Thanks! One last thing though, if you prefer I can create a separate question but, I tried wrapping the `NSLayoutConstraint.constant` value change in a `UIView animateWithDuration:...` call in hopes of animating the resizing but it didn't animate. I was about to try CoreAnimation directly now, but was wondering if you know if it's even possible? – SaldaVonSchwartz Jul 31 '13 at 21:04
  • You need to force UIKit to perform the layout pass inside the animation block. You can just do `[self.topView layoutIfNeeded]` inside the block, or if you're using the full animation method with options, you can pass the `UIViewAnimationOptionLayoutSubviews` flag. – rob mayoff Jul 31 '13 at 21:05