Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

download Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

of 30

Transcript of Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    1/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2

    Beginning Auto Layout in iOS 6: Part

    2/2

    Update note: Check out our newer version of this tutorial, updated to

    Swift and iOS 8: Beginning Auto Layout Tutorial in Swift: Part 2.

    This tutorial is an abbreviated version of one of the chapters from our

    new book iOS 6 By Tutorials. Matthijs Hollemans wrote this the

    same guy who wrote the iOS Apprentice Series. Enjoy!

    In part 1 of this tutorialyou saw that the old struts-and-springs

    model for making user interfaces cannot easily solve all layout

    problems. The new Auto Layout feature from iOS 6 is the solution,

    but because this technology is so powerful it is also a bit more tricky

    to use.

    In this second part and final part of the tutorial series, youll continue

    learning all about constraints and how to apply them!

    As bold as a userconstraint

    Maybe you noticed that some of the T-bars in the canvas are thicker than others. The bold ones are called userconstraints , and unlike the thin ones you can delete them. However, when you delete a user constraint, Interface

    Builder will often put a non-deletable constraint in its place. Youwill soon see why.

    In the Document Outline, user constraints have a blue icon:

    Select the Vertical Space (40) constraint and tap the Delete key on your keyboard. The T-bar between the two buttons

    disappears and is replaced by a new Vertical Space constraint that goes all the way to the bottom:

    Matthijs Hollemans on September 19, 2012

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/user-constraints-document-outlinehttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/user-constraints-document-outlinehttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/user-constraints-document-outlinehttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/user-constraints-document-outlinehttp://cdn4.raywenderlich.com/wp-content/uploads/2012/09/iOS6_feast_AutoLayout.pnghttp://cdn4.raywenderlich.com/wp-content/uploads/2012/09/iOS6_feast_AutoLayout.pnghttp://cdn4.raywenderlich.com/wp-content/uploads/2012/09/iOS6_feast_AutoLayout.pnghttp://www.raywenderlich.com/?p=20881http://www.raywenderlich.com/?page_id=19968http://cdn4.raywenderlich.com/wp-content/uploads/2012/09/iOS6_feast_AutoLayout.pnghttp://cdn4.raywenderlich.com/wp-content/uploads/2012/09/iOS6_feast_AutoLayout.pnghttp://cdn4.raywenderlich.com/wp-content/uploads/2012/09/iOS6_feast_AutoLayout.pnghttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/user-constraints-document-outlinehttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/user-constraints-document-outlinehttp://www.raywenderlich.com/u/Hollancehttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/user-constraints-document-outlinehttp://www.raywenderlich.com/?p=20881http://www.raywenderlich.com/?page_id=5002http://www.raywenderlich.com/?page_id=19968http://www.raywenderlich.com/83130/beginning-auto-layout-tutorial-swift-part-2http://cdn4.raywenderlich.com/wp-content/uploads/2012/09/iOS6_feast_AutoLayout.pnghttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2http://www.raywenderlich.com/u/Hollance
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    2/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 2

    This new constraint has a purple icon and does not have a bold line, meaning that you cannot delete this one. The two

    buttons are no long er connected vertically, although they are still left-aligned due to the Leading Alignment constraint.

    Why does this happen? Why does Interface Builder attach a new Vertical Constraint to the button, even though you just

    told it to delete such a constraint? The answer is this:

    For each view there must always be enough constraints to determine both its position and size.

    That is the most important rule to remember when it comes to using Auto Layout. If there arent enough constraints, then

    Auto Layout w ill be unabl e to calculate where your views should be positioned or how big they sho uld be. Such a layout

    is considered to be invalid. You will see examples of such invalid layouts later on.

    Interface Builder tries very hard to prevent you from making layouts that are invalid. The size of these two buttons is

    known because buttons know how big they should be, based on their text, background image, and so on intrinsic

    content size, remember? So thats not a problem. The X-position of the top button is also known because its left edge is

    aligned with the bottom button, and the bottom button is always horizontally centered. The only unknown is the Y-

    position.

    Previously, the two buttons were connected with a Vertical Space. That was enough to determine the Y-position of the

    top button. But if you delete that Vertical Space, then the top button has nothing to anchor it vertically in the view. Itcannot just float there because then Auto Layout has no way to determine what its Y-coordinate should be.

    To prevent this from happening, Interface Builder needs to pin the button somewhere and the bottom edge is closest.

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/rage-pin-buttonshttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/after-deleting-user-constraint
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    3/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 3

    Funnily enough, if you run the app and flip to landscape, it still seems to work. The screen looks exactly the same as it

    did before. That is true, but your design is fundamentally different: both buttons are now connected to the bottom of the

    window. This means that if the bottom button moves, the top one doesnt move with it. (Note that either solution is fine, it

    just depend s on what you want your app to do . But i n this example, you want to ha ve a vertical connection between the

    two buttons.)

    To illustrate this, select the Vertical Space constraint between the lower button and the screens edge. Go into the

    Attributes inspector. Its Constant should currently read Auto, and Standard is checked because this is a standard

    margin space. Change it to 40.

    Because the buttons are not connected, only the lower button moves upward the top button stays put:

    Notice that changing the Constant value of the constraint promoted it to a bold user constraint.

    Needles and pins

    Lets connect the two buttons again. So far you have made constraints by dragging the buttons on the canvas, but you

    can also make them afterwards. Hold down the Cmdkey and click both buttons to select them. From the Editormenu,

    choose Pin\Vertical Spacing.

    You can also use the little panel in the bottom-right corner to make this constraint:

    It pops up the following menu:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/shortcut-menu-pinhttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/only-bottom-button-moves-up
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    4/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 4

    Regardless of the method you choose, this adds a new constraint between the two buttons:

    The new constraint is a Vertical Space constraint with a Constant of 20 points. That is because the distance between the

    two buttons was 20 points at the time you made this connection.

    Notice that the old Vertical Space from the upper-most button to the bottom edge is still there. This constraint the one

    that says Vertical Space (104) is no longer needed, so delete it.

    Previously when you deleted a blue constraint, a purple one took its place. Now that does not happen, because the

    remaining constraints are sufficient to position all the views. Interface Builder only adds new constraints when the

    existing ones are no longer adequate.

    You should now have the following constraints:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/pin-vertical-spacinghttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/pin-menu
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    5/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 5

    Select the bottom Vertical Space (by clicking on the canvas) and change its Constant from 40 back to Standard. This

    should not only move the bottom button downwards, but the top button as well, because they are connected again.

    A little runtime excursion

    Youve seen a bit of the basics now: you know how to place controls using the guides, how to align them relative to one

    another, and how to put space between controls. Over the course of this tutorial you will also use the other options from

    the Align and Pin menus.

    Playing with this in Interface Builder is all well and good, but lets see how this works at runtime. Add the following

    method to ViewController.m:

    -(IBAction)buttonTapped:(UIButton *)sender

    {

    if([[sender titleForState:UIControlStateNormal]isEqualToString:@"X"])

    [sender setTitle:@"A very long title for this button"

    forState:UIControlStateNormal];

    else

    [sender setTitle:@"X"forState:UIControlStateNormal];}

    This simply toggles between a long title and a short title for the button that triggered the event. Connect this action

    method to both of the buttons in Interface Builder: Ctrl-drag from each button to Files Owner and select buttonTapped:i n

    the popup.

    Run the app and tap the buttons to see how it behaves. Perform the test in both portrait and landscape orientations.

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/restored-constraints
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    6/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 6

    Regardless of which button has the long title and which has the short title, the layout always satisfies the constraints you

    have given it:

    The lower button is always center-aligned in the window, horizontally.

    The lower button always sits 20 points from the bottom of the window.

    The top button is always left-aligned with the lower button.

    That is the entire specification for your user interface.

    For fun, select both buttons in Interface Builder and from the Align menu pick Right Edges. Now run the app again and

    notice the differences.

    Repeat, but now choose Align\Horizontal Centers. That will always center the top button with respect to the bottom

    button. Run the app and see how the buttons act when you tap them.

    Fixing the width

    The Pin menu has an option for Widths Equally. If you set this constraint on two views, then Auto Layout will always

    make both views equally wide, based on which one is the largest. Lets play with that for a minute.

    Select both buttons and choose Pin\Widths Equally. This adds a new constraint to both buttons:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/long-and-short-titles
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    7/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 7

    Note: If you get an extra unintended constraint between one of the buttons and the superview, select the two

    buttons and select Align\Horizontal C enters again.

    You have seen this type of constraint before, in the first part of this tutorial. It looks like the usual T-bar but in the middle it

    has a circle with an equal sign.

    In the Document Outline this shows up as a single Equal Widths constraint:

    Changing the label text on one button will now change the size of the other one as well.

    Change the bottom buttons label to X, just to make it really small. You will notice that the top button no longer fits its

    text:

    So how does Interface Builder know which buttons size to use for both of them? If you pay close attention, youll see that

    a Width constraint was added to the button with the truncated text:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/top-button-text-no-longer-fitshttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/equal-widths-in-document-outlinehttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/buttons-widths-equally
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    8/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 8

    Interface Builder does this to force the button to become smaller than what it would ideally be, in order to comply with the

    Equal Widths constraint.

    Obviously this is not what you want, so select the top button and choose Size to Fit Contentfrom the Editormenu (or

    press Cmd =). Now the text fits inside the button again or rather, the button fits around the text and the Width

    constraint is g one.

    Run the app and tap the buttons. The buttons always have the same width, regardless of which one has the largest

    label:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/width-constraint-on-truncated-buttonhttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/width-constraint-on-truncated-button-in-document-outline
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    9/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 9

    Of course, when both labels are very short, both buttons will shrink equally. After all, unless there is a constraint that

    prevents, buttons will size themselves to fit their content exactly, no more, no less. What was that called again? Right, the

    intrinsic content size.

    Intrinsic Content Size

    Before Auto Layout, you always had to tell buttons and other controls how big they should be, either by setting their

    frame or bounds properties or by resizing them in Interface Builder. But it turns out that most controls are perfectly

    capable of determining how much space they need, based on their content.

    A label knows how wide and tall it is be cause it knows the length of the text that has be en set on it, as well as the

    font size for that text. Likewise for a button, which might combine the text with a background image and some

    padding for the rounded corners.

    The same is true for segmented controls, progress bars, and most other controls, although some may only have a

    predetermined height but an unknown width.

    This is known as the intrinsic content size, and it is an important concept in Auto Layout. You have already seen it

    in action with the buttons. Auto Layout asks your controls how big they need to be and lays out the screen based

    on that information.

    You can prevent this by setting an explicit Width or Height constraint on a control. If you resize the control by hand,

    then Interface Builder will set such an explicit constraint for you. With the Size to Fit Contentcommand, you

    remove any fixed Width or Height constraints and let the control determine its intrinsic content size again.

    Usually you want to use the intrinsic content size, but there are some cases where you may notwant to do that.

    Imagine what happens when you set an image on a UIImageView if that image is much larger than the screen. You

    usually want to give image views a fixed width and height and scale the content, unless you want the view to resize

    to the dimensions of the image.

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/buttons-equal-widths-in-app
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    10/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 10

    So what happens when one of the buttons has a fixed Width constraint on it? Buttons calculate their own size, but you

    can override this by giving them a fixed width. Select the top button and choose Pin\Widthfrom the menu. This adds a

    solid T-bar below the button:

    Because this sort of constraint only applies to the button itself, not to its superview, it is listed in the Document Outline

    below the button object. In this case, you have fixed the button to a width of 73 points.

    Run the app and tap the buttons. What happens? The button text does change, but it gets truncated because there is not

    enough room:

    Because the top button has a fixed-width constraint and both buttons are required to be the same size, they will never

    shrink or grow.

    Note:You probably wouldnt set a Width constraint on a button by design it is best to let the button use its intrinsic

    size but if you ever run into a layout problem where you expect your controls to change size and they dont, then

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/button-text-clippedhttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/button-fixed-width-constraint
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    11/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 1

    double check to make sure Interface Builder didnt sneak a fixed Width constraint in there.

    Play around with this stuff for a bit to get the hang of pinning and aligning views. Get a feel for it, because not everything

    is immediately obvious. Just remember that there must always be enough constraints so that Auto Layout can determine

    the position and size for all views.

    Gallery example

    You should now have an idea of what constraints are and how you can build up your layouts by forging relationships

    between the different views. In the following sections, you will see how to use Auto Layout and constraints to create

    layouts that meet real-world scenarios.

    Lets pretend you want to make an app that has a gallery of your favorite programmers. It looks like this in portrait and

    landscape:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/rage-enough-constraints
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    12/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 12

    The screen is divided into four equal quarters. Each quarter has an image view and a label. How would you approach

    this?

    Lets start by setting up the basic app. You can use your existing Constraints app by deleting the buttons and reusing

    the view.

    Or, you can create a new project using the Single View Application template and name it as you like, for instance,

    Gallery. This will just use a nib, so disable the storyboards option.

    Open ViewController.xib. From the Object Library, drag a plain view object onto the canvas. Resize the view so that it is

    160 by 230 points, and change its background color to be something other than white (I made mine green):

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/gallery-preview
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    13/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 13

    This view has four constraints to keep it in place. Unlike a button or label, a plain UIViewdoes not have an intrinsic

    content size. There must always be enough constraints to determine the position and size of each view, so this view also

    needs constraints to tell it what size it needs to be.

    You may wonder, where are these size constraints? In this case, the size of the view is implied by the size of the

    superview. The constraints in this layout are two Horizontal Spaces and two Vertical Spaces, and these all have fixed

    lengths. You can see this in the Document Outline:

    The width of the green view is calculated by the formula width of superview minus (109 + 51) and its height by the

    formula height of superview minus (153 + 77). The space constraints are fixed, so the view has no choice but to resize.

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/constraints-for-uiview-in-document-outlinehttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/view-with-auto-layout
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    14/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 14

    When you rotate the app, the dimensions of the superview change from 320460 to 480300. Plug this new width and

    height into these formulas, and youll get the new size of the green view.

    You can see this for yourself when you run the app and flip to landscape, but you can also simulate it directly in Interface

    Builder.

    Select the top-most view in the nib and go to the Attributes inspector. Under the Simulated Metrics section, change

    Orientation to Landscape:

    This gives you an instant preview of what the nibs layout will look like in landscape orientation. The green view has

    resized in order to satisfy its Horizontal and Vertical Space constraints.

    Switch back to portrait orientation.

    Note:There are two main reasons why you would drop a plain UIViewonto a nib: a) Youre going to use it as a

    container for other views, which helps with organizing the content of your nibs or b) It is a placeholder for a custom

    view or control, and you will also set its Class attribute to the name of your own UIViewor UIControl subclass.

    You may not always want your UIView to resize when the device rotates, so you can use constraints to give the view a

    fixed width and/or height. Lets do that now. Select the green view and from the Pinmenu, choose Width. Select the view

    again and choose Pin\Height.

    You have now added two new constraints to the view, a 160 point Width constraint and a 230 point Height constraint:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/simulated-metrics-landscape
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    15/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 15

    Because Width and Height apply to just this view, they are located in the Document Outline under the View itself.

    Usually, constraints express a relationship between two different views for example, the Horizontal and Vertical Space

    constraints are between the green view and its gray superview but you can consider the Width and Height constraints

    to be a relationship between the view and itself.

    Run the app. Yup, looks good in portrait. Now flip over to landscape. Whoops! Not only does it not look like you wanted

    the view has changed size again but the Xcode debug pane has dumped a nasty error message:

    Gallery[68932:11303]Unable to simultaneously satisfy constraints.

    Probably at least one of the constraints inthe following list is one you don't

    want. Try this: (1) look at each constraint and try to figure out which you don't expect;

    (2)findthe code that added the unwanted constraint or constraints and fix it. (Note: If

    you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the

    documentation forthe UIView property translatesAutoresizingMaskIntoConstraints)

    ( "",

    "",

    "",

    "",

    ""

    )

    Will attempt to recover by breaking constraint

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/width-and-height-constraints-on-uiview
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    16/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 16

    Break on objc_exception_throw to catch this inthe debugger.

    The methods inthe UIConstraintBasedLayoutDebugging category on UIView listed in

    may also be helpful.

    Remember when I said that there must be enough constraints so that Auto Layout can calculate the positions and sizes

    of all the views? Well, this is an example where there are too many constraints. Whenever you get the error Unable to

    simultaneously satisfy constraints, it means that your constraints are conflicting somewhere.

    Lets look at those constraints again:

    There are six constraints set on the green view, the four Spacing constraints you saw earlier and the new Width and

    Height constraints that you have just set on it. So where is the conflict?

    Well, in portrait mode there shouldnt be a problem because the math adds up. The width of the superview is 320 points.

    If you add the lengths of the Horizontal Space constraints and the Width of the view, then you should also end up at 320.

    The way I have positioned the view, that is: 51 + 160 + 109 = 320 indeed. Likewise, the vertical constraints should add

    up to 460.

    But when you rotate the device to landscape, the window (and therefore the superview) is 480 points wide. That means

    51 + 160 + 109 + ? = 480. There are 160 extra points that need to go somewhere in that equation and Auto Layout

    doesnt know where to get them. Likewise for the vertical axis.

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/conflicting-constraints
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    17/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 17

    The conflict here is that either the width of the view is fixed and one of the margins must be flexible, or the margins are

    fixed and the width must be flexible. So one of these constraints has to go. In the above example, you want the view to

    have the same width in both portrait and landscape, so the trailing Horizontal Space has got to go.

    Remove the Horizontal Space at the right and the Vertical Space at the bottom. The nib should look like this:

    Now the view has just the right number of constraints to determine its size and position, no more, no less. Run the app

    and verify that the error message is gone and that the view stays the same size after rotating.

    Note:Even though Interface Builder does its best to prevent you from making invalid layouts, it cannot perform

    miracles. At least Auto Layout spits out a detailed error message when something is wrong. You will learn more

    about analyzing these error messages and diagnosing layout problems in Intermediate Auto Layout in iOS 6 by

    Tutorials.

    Painting the portraits

    Drag a label onto the green view. Notice that now the guides appear within that green view, because it will be the

    superview for the label.

    http://www.raywenderlich.com/?page_id=19968http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/conflicting-constraints-fixed
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    18/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 18

    Position the label in the top-left corner against the guides. This will add two Space constraints to anchor the label in the

    top-left corner of the green view:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/drag-label
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    19/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 19

    Notice that these two new Horizontal and Vertical Space constraints are listed under the green views Constraints

    section, not in the main view.

    Now move the green view around a bit. Youll see that only the constraints between the green view and its superview

    change, but those for the label dont. The label always stays put in the same place, relative to the green view.

    Select the label and place it against the bottom margin, horizontally centered. Then drag a new image view object on to

    the nib, and make the layout look like this:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/label-constraints
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    20/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 20

    The image view is pinned to the top, left and right edges of its superview, but its bottom is connected to the top of the

    label with a standard spacing.

    Download the resources for this tutorialand unzip the file. You will find an Imagesfolder add this folder into your

    project. Set Ray.pngas the image for the image view, change the image views mode to Aspect Fit and set its

    background color to white. Change the labels text to say Ray.

    Your layout should now look like this:

    http://cdn5.raywenderlich.com/downloads/AutoLayoutImages.ziphttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/image-view-in-gallery
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    21/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 2

    Notice that Interface Builder has placed a Height constraint on the label now. This happened the moment you set the

    image on the image view.

    Interface Builder tries to prevent what are known as ambiguous layouts. If neither the image view nor the label has a

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/label-fixed-heighthttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/gallery-with-ray
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    22/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 22

    fixed height, then Auto Layout doesnt know by how much to scale each if the height of the green view should change.

    (Interface Builder seems to ignore for now that the green view actually has a fixed Height constraint set on it.)

    Lets say at some point in your app the green view becomes 100 points taller. How should Auto Layout distribute these

    new 100 points among the label and the image view? Does the image view become 100 points taller while the label

    stays the same size? Or does the label become taller while the image view stays the same? Do they both get 50 points

    extra, or is it split 25/75, 40/60, or in some other possible combination?

    Auto Layout i s no t going to guess, so Interface Builder fixes this problem for us by giving the l abel a fixed heigh t. It

    could also have given the image view a fixed height, but the label makes more sense.

    For now, lets just live with the Height constraint on the label.

    Note:The proper solution to this small l ayout problem is to change the Content Compression R esistance Priority

    of the label. You will learn more about that later on. If you cant wait, then go into the Size inspector for the label

    and set the vertical Content Compression Re sistance Priority to 751. The Height constraint on the la bel should now

    disappear.

    Adding the other heads

    Move the green view onto the main views top-left corner. Recall that the green view had Horizontal Space and Vertical

    Space constraints that determined its position in the parent view. It still has those, but they are now set to a value of 0

    they are represented by the thick blue lines (with white borders) at the top and left edges of the window:

  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    23/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 23

    So even though the view sits completely in the corner, it still needs constraints to anchor it there. Think of these as

    margins with a value of 0.

    Select the green view and tap Cmd-D to duplicate it. Move the duplicate into the top-right corner:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/view-in-top-left-corner
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    24/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 24

    Duplicate two more times and put these copies in the bottom-left and bottom-right corners, respectively.

    Change the screen design to the following:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/green-view-in-top-right-corner
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    25/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 25

    Those are some good-looking programmers! :-)

    Run the app. It looks good in portrait, but not so much in landscape:

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/gallery-landscape-badhttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/gallery-design
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    26/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 26

    It should be pretty obvious what went wrong: youve set a fixed width and height on the four brightly-colored container

    views, so they will always have those sizes, regardless of the size of their superview.

    Select the Width (160) and Height (230) constraints from all four views and delete them. If you run the app now, youll get

    something like this. Also not very good:

    This looks very much like the problem we solved in the introduction, so if you think back to how we solved that, youll

    recall that we gave the views equal widths and heights.

    Select all four colored views and choose Pin\Widths Equally. Select the views again and choose Pin\Heights Equally.

    Run the app again and rotate the device. Hmm it still looks exactly the same as before. Why?

    Well, if you look at the screenshot youll see that all the views dohave the same height, and they also appear to have the

    same width (the green and brown views are partially obscured by the yellow and blue ones), so our constraints are

    being met. Its just not the width and height that you want them to have. There must be other constraints that are getting

    in the way.

    Sure enough, if you look at the constraints on these views, youll see that they also have Horizontal and Vertical Spaceconstraints that force them into place (look at list of constraints on the main view, not the four subviews):

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/gallery-landscape-bad-2
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    27/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 27

    Whats worse, you cant even delete that constraint. Its T-bar is not bold and the constraint is not blue, so Interface

    Builder put it there in order to prevent a layout problem.

    So why does it do that? Just saying that all four views must have equal sizes is not enough to determine what those

    sizes should actually be, because Auto Layout does not know how these four views are connected to each other. They

    appear side-by-side in the design, but there are no actual constraints between them. Auto Layout does not know that it

    needs to split the window width between the Ray and Matthijs boxes.

    If Auto Layout cant figure this out by itself, you have to tell it.

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/bad-h-space
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    28/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 28

    Select the Ray and Matthijs boxes and choose Pin\Horizontal Spacing. Because the boxes are side-by-side, this adds a

    Horizontal Space constraint with size 0 between them, and that is enough to let Auto Layout know how these two views

    are related.

    Important:Interface Builder does not automatically remove the leading Horizontal Space between the superview and

    the yellow box (the one from the screenshot above), but it did promote it to a user constraint (a fat bar). You can now

    delete this space. If you dont, you will get an Unable to simultaneously satisfy constraints error during runtime when

    you flip to landscape.

    Run the app. It should now look like this:

    That looks a bit better already. The four boxes now have equal widths, but the heights are still wrong. The solution is

    similar: put a Vertical Space between the Ray and Dennis Ritchie boxes and remove the Vertical Space between the

    Dennis Ritchie box and the top of the window.

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/gallery-landscape-bad-3http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/meme-related
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    29/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2 29

    Run the app again, and this time it looks all right:

    Notice that the Dennis Ritchie label is not centered below its image view. This originally happened to me when I typed

    that text into the label. The label was initially centered in the view, but Interface Builder decided it knew better and

    replaced that centering constraint with a Horizontal Space. If this happened to you, too, then select that label and choose

    Align\Horizontal Center in Containerto fix it.

    A qu ick note on the i mage views: they stretch out because you have not given them a fixed size. You may not know it, but

    thats intentional on your part. The image views wouldnt fit in landscape mode otherwise. However, if you want an

    image view to keep its original aspect ratio, then youre out of luck. You cannot achieve the following effect using

    Interface Builder:

    Unfortunately, Interface Builder does not currently provide a way to make constraints that keep the aspect ratio of a viewintact. To do that, you need to create and set the constraints programmatically. You will learn how to do that in

    Intermediate Auto Layout in iOS 6 by Tutorials.

    Tip:You have seen that you can preview what the UI will look like in landscape by changing the Orientation setting

    under Simulated Metrics. You can also test the resizing behavior of your views directly in Interface Builder.

    Select the main view. Under Simulated Metrics, set Size to Freeform. This adds resize handles around your nib that you

    can use to mold it into any shape you want. Auto Layout will recalculate the layout on-the-fly:

    http://www.raywenderlich.com/?page_id=19968http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/gallery-aspect-ratiohttp://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/gallery-landscape-ok
  • 7/25/2019 Beginning Auto Layout in IOS 6_ Part 2_2 - Ray Wenderlich

    30/30

    12/3/2015 Beginning Auto Layout in iOS 6: Part 2/2 - Ray Wenderlich

    However, be careful with this. Sometimes Interface Builder will insert new constraints of its own when youre resizing, as

    it did here in the bottom-right corner (it added a Horizontal Space). It may also delete existing constraints when they fall

    outside of the nib bounds.

    Where To Go From Here?

    If youve made it this far, congratulations you now know what Auto Layout is all about, and have experimented with the

    basics! But theres a lot left to learn

    The tutorial you have just read is only the first half of the Beginning Auto Layout chapter from the book iOS 6 by Tutorials.

    The second half teaches how to use Auto Layout to create more real-world screen layouts, and everything else you

    need to know about using Auto Layout from Interface Builder.

    But like any visual design tool, Interface Builder has its limitations and sometimes it just makes more sense to work with

    the NSLayoutConstraint objects directly from code. iOS 6 by Tutorials dedicates an entire chapter to this topic,

    Intermediate Auto Layout. So if you want to get to the bottom of Auto Layout, get the book!

    Matthijs Hollemans

    Matthijs Hollemans is an independent iOS developer and designer who lives to create

    awesome software. His focus is on iPad apps because he thinks tablets are way cooler

    than phones. Whenever he is not glued to his screen, Matthijs plays the piano, is into

    healthy and natural living, and goes out barefoot running. Visit his website at

    http://www.hollance.com.

    http://www.hollance.com/http://www.raywenderlich.com/u/Hollancehttp://www.raywenderlich.com/?page_id=19968http://www.raywenderlich.com/?page_id=19968http://www.raywenderlich.com/20897/beginning-auto-layout-part-2-of-2/freeform