How do I create a constraints based view that resizes between iPhone 5 and iPhone 4 comparable to Anchor operation?

Warren  P picture Warren P · Feb 25, 2013 · Viewed 39.6k times · Source

The sort of classic Springs and Struts, aka "Anchor and Align", or "Autosizing masks" is the only sort of resize-management I understand. However in XCode 4.6, "autolayout" using constraints as introduced in iOS 6, is the default, and it makes certain simple things harder, while making a whole world of new arrangements possible, once you learn how. (To be clear, some users might only care to get a simple view working without fighting autolayout battles, so a workaround was suggested early on by Matt, of turning off Autolayout, which is reproduced below)

iOS 6 Layout Constraints, the Interface Builder system of editing constraints, I do not understand.

enter image description here

Where XCode Interface Builder automatically creates constraints (such as at the edges of the view) it seems to behave in a way I understand.

What I don't understand is why in the .xib shown here, and also available here, why I can't get the green and magenta regions to maintain a constant border (the white area between them) that gets no thicker and no thinner, no matter what happens to the size of the view.

That means I need the green area not to resize vertically and only resize horizontally, but it's insisting on anchoring itself to the bottom of the form, and although starting from a new blank nib again, will restore interface builder so it will notice adjacency of the green and magenta views again, once interface builder has gone "stupid" it insists on only defining the green view's bottom edge in terms of its distance from its parent view's bottom edge, and won't (for any amount of fiddling) do otherwise using mere drag and drop operations. I have also experimented with the Pin commands and haven't found a pin command that works.

No amount of fighting with interface builder menus or dragging and dropping seems to be enough, to get it to let go of one of the constraints. I can't figure out what I'm supposed to do. Delete a constraint? How? Constraints can't be deleted at all as far as I can see, either from the IB Objects pane or from the Utilities -> Size inspector. There is a delete option but it's grayed out in the drop down menu that appears when you click the "gear" icon button in the constraints area.

Ideally I'd love it if the green area resized as the view gets wider, but not as it gets taller or shorter. I thought this was obvious in every other tool, but in XCode+Autolayout, it's either not resize at all, or resize in all four directions. I can't delete or remove the constraints that are doing things I don't want to do. Do you have to have four constraints on each view that is inside another view?

(Update 1: You can not remove any constraint that would result in an ambiguous or unspecified layout.)

(Update 2: Sometimes if a uiview pane won't snap to a sibling, deleting that uiview and trying again will allow it to naturally "snap" to a sibling, and the constraint will be made relative to a sibling view object instead of a parent.)

(Update 3: Matt deleted his workaround, I've reproduced it below.)

Workaround for people who didn't want Autolayout in the first place, and who just wanted the old springs and struts back:

Step 1: Turn Off Autolayout:

enter image description here

Step 2: Select the Correct Autoresizing Masks:

enter image description here

Answer

jrturton picture jrturton · Feb 26, 2013

The key to editing constraints in interface builder is never to drag and drop anything once you've added it to the view. Move and arrange things by editing the constraints instead. Use the pinning menu to create new constraints. You can delete unwanted constraints once you've added sufficient new ones to unambiguously replace the automatically added system constraints.

In your case I created the following constraints:

enter image description here

I renamed your views "Green" and "Magenta" to make things clearer in the document navigator. What I have done is:

  • Pin the vertical spacing between the views
  • Pinned each view to the left and right sides
  • Pinned the top view to a set height and a set distance from the top of the superview
  • Pinned the bottom of the bottom view to the bottom of the superview.

This gives you the layout you want, I think. I have written in excruciating detail about this here, if you want to read more.