auto layout pg(a definitive guide for ios programmers)

30
Cocoa Auto Layout Guide

Upload: ankitxankit

Post on 13-Jan-2016

171 views

Category:

Documents


0 download

DESCRIPTION

AutolayoutPG of IOS helps in creating creating layouts for the Iphones. Especially useful for the IOS programmers. You will be able to create different layouts for your Iphone mobile.IOS developing environment.

TRANSCRIPT

Page 1: Auto Layout Pg(A definitive guide for IOS programmers)

Cocoa Auto LayoutGuide

Page 2: Auto Layout Pg(A definitive guide for IOS programmers)

Contents

About Cocoa Auto Layout 4At a Glance 4

Constraints Express Relationships Between Views 7About Constraints 7

Constraints Can Be Inequalities 7Constraints Have a Priority Level 8Constraints May Cross View Hierarchies 8

Create Constraints Programmatically Using an ASCII-Art Format String 9Constraints are Mostly Immutable 10Install Constraints 10Auto Layout Degrades Gracefully with Unsatisfiable Constraints 11

Visual Format Language 13Visual Format Syntax 13Visual Format String Grammar 14

Dividing Responsibility Between Controllers and Views 17A View Specifies its Intrinsic Content Size 17A Controller Specifies How Important the Intrinsic Size Is 18Views Must Tell the Auto Layout System if Their Intrinsic Size Changes 18Layout Operates on Alignment Rectangles, Not Frames 18Views Indicate Baseline Offsets 19

Debugging 20Debugging Workflow 20Handling Ambiguity 22

Core Layout Runtime 24

Adopting Auto Layout 27

Document Revision History 29

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

2

Page 3: Auto Layout Pg(A definitive guide for IOS programmers)

Figures

Debugging 20Figure 4-1 Constraint debugging window illustrating ambiguity 22Figure 4-2 Constraint debugging window illustrating alternate resolution of ambiguity 23

Adopting Auto Layout 27Figure 6-1 Button layout using springs and struts 27

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

3

Page 4: Auto Layout Pg(A definitive guide for IOS programmers)

You use the Cocoa Auto Layout system to define layout constraints for user interface elements. Constraintsrepresent relationships between user interface elements such as “these views line up head to tail,” or “thisbutton should move with this split view subview.” When laying out the user interface, a constraint satisfactionsystem arranges the elements in a way that most closely meets the constraints.

Important: This document has not been revised to specifically describe the auto layout behavior on iOS.It is included in the iOS Library because the underlying layout concepts are the same between OS X andiOS.

At a GlanceCocoa Auto Layout lets you define rules for the layout of elements in your user interface. For example, youmight want to specify that a text label should be anchored the appropriate distance (as defined by Aquaguidelines) from the sides of its window and an adjacent text field, and that the label should occupy just asmuch area as required by the string. Such a scenario is illustrated in the window on the left in the followingdiagram.

Cocoa Auto Layout allows individual views to declare their own preferred size, which means you don’t haveto specify new layout if the label’s text changes—for example, because of localization, as illustrated in the rightwindow. You don’t even have to specify new layout for languages like Hebrew and Arabic in which the left toright ordering of elements themselves should generally be reversed.

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

4

About Cocoa Auto Layout

Page 5: Auto Layout Pg(A definitive guide for IOS programmers)

Cocoa Auto Layout thus improves the traditional division of responsibility between controllers and views.Rather than you writing a monolithic, omniscient controller that calculates where views need to go for a givengeometry, views use constraints to declare where they want to be. Constraints represent relationships betweenuser interface elements such as “these views line up head to tail,” or “this button should move with this splitview subview.” Constraints themselves are objects—instances of NSLayoutConstraint—that you install onviews.

For more about how you architect your application to use the Auto Layout system, see “Dividing ResponsibilityBetween Controllers and Views” (page 17).

Typically, you specify the constraints in Interface Builder. Suppose you drag a text field out of the library, snapit into the bottom left corner of a window, then drag-resize the right edge until it snaps into the bottom rightcorner. Nothing further is needed to specify that when the window is resized the text field should stretchhorizontally. If you need to create constraints programmatically, you typically do so using an ASCII-art inspiredformat string. For example, you could create a constraint to keep two buttons the standard Aqua spacing apartusing a format string like this: [button1]-[button2].

For more about constraints and how to create and use them, see “Constraints Express Relationships BetweenViews” (page 7).

Cocoa Auto Layout offers several features that can help you find problems if your views are not positioned asyou expected. In particular, Auto Layout provides a runtime visualization.

For more about diagnosing problems with constraints, see “Debugging” (page 20).

To determine the position of views, Auto Layout adds two passes to the process of rendering a window (inaddition to the “display” pass Cocoa had previously used). In some situations, you may take advantage of thesepasses to perform custom layout of your own or to force re-layout of the user interface.

For more about the the Auto Layout engine, see “Core Layout Runtime” (page 24).

The design of the Auto Layout architecture makes it fairly straightforward to incrementally move a project thatuses the springs and struts model for user interface layout to use the Auto Layout system. By default the AutoLayout system translates old-style autosizing masks into constraints to provide compatibility.

For more about converting an existing project, see “Adopting Auto Layout” (page 27).

There are several code examples that illustrate how you can use the Auto Layout system—seeCocoaAutolayoutDemos .

The following WWDC videos provide another introduction to auto layout as well as example layouts:

● WWDC 2012: Introduction to Auto Layout for iOS and OS X

● WWDC 2012: Auto Layout by Example

About Cocoa Auto LayoutAt a Glance

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

5

Page 6: Auto Layout Pg(A definitive guide for IOS programmers)

● WWDC 2012: Best Practices for Mastering Auto Layout

About Cocoa Auto LayoutAt a Glance

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

6

Page 7: Auto Layout Pg(A definitive guide for IOS programmers)

Constraints represent relationships between user interface elements such as “these views line up head to tail,”or “this button should move with this split view subview.”

About ConstraintsA constraint is basically a statement of the form y = m*x + b where

● y and x are attributes of views.

● An attribute is one of left, right, top, bottom, leading, trailing, width, height, centerX,centerY, and baseline.

● The attributes leading and trailing are the same as left and right in English, but the UI flips in aright-to-left environment like Hebrew or Arabic. When you create constraints using Interface Builder orthe visual format strings (see “Create Constraints Programmatically Using an ASCII-Art Format String” (page9)), leading and trailing are the default values.

● m and b are floating point values.

The following (presented as pseudocode) represents a concrete example of a constraint:

button1.right == button2.left - 12.0

Constraints are not directional, and there are no restrictions on cycles. Layout itself is neither top down norbottom up. Instead, all constraints are considered at the same time, and elements laid out in such a way thatbest satisfies all of the constraints.

Constraints Can Be InequalitiesThe relation in a constraint does not have to be ==; it can also be <= or >=. For example:

button1.width >= 100.0

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

7

Constraints Express Relationships Between Views

Page 8: Auto Layout Pg(A definitive guide for IOS programmers)

Constraints Have a Priority LevelConstraints have a priority level. A priority level is a floating point value. Constraints with higher priority levelsare satisfied before constraints with lower priority levels. The default priority level isNSLayoutPriorityRequired, which means that the constraint must be satisfied exactly. The layout systemgets as close as it can to satisfying an optional constraint, even if it cannot completely achieve it. If a constrainta == b is optional, it means that abs(a - b) should be minimized.

Priority levels allow you to express useful conditional behavior. For example, they are used to express that allcontrols should always be sized to fit their contents, unless something more important prevents it. For moredetail on this example, see “A View Specifies its Intrinsic Content Size” (page 17).

Constraints May Cross View HierarchiesConstraints can, with some restrictions, cross the view hierarchy. In Mail, for example, by default the Deletebutton in the toolbar lines up with the message table. In Desktop Preferences, the checkboxes at the bottomof the window align with the split view pane they operate on.

It is not legal for a constraint to cross through a view that is manually laid out, or through a view that has abounds transform (such as a scroll view)—you can think of such views as barriers. There’s an inside world andan outside world, but the inside cannot be connected to the outside by constraints.

Constraints Express Relationships Between ViewsAbout Constraints

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

8

Page 9: Auto Layout Pg(A definitive guide for IOS programmers)

Create Constraints Programmatically Using an ASCII-Art FormatStringYou represent constraints using instances of NSLayoutConstraint. To create constraints, you typically useconstraintsWithVisualFormat:options:metrics:views:. The first argument is an ASCII-art–inspiredvisual format string that provides a visual representation of the layout you want to describe. A view is inrepresented in square brackets, and a connection between views is represented using a hyphen (or two hyphensseparated by a number to represent the number of points apart the views should be). Examples and a grammarfor the visual format language are given in “Visual Format Language” (page 13).

For example, for this layout

you might represent the relationship between button1 and button2 as

[button1]-12-[button2]

A single hyphen denotes the standard Aqua space, so you could represent the relationship with just

[button1]-[button2]

You pass the visual format string as the first argument toconstraintsWithVisualFormat:options:metrics:views:. The views come from the viewsdictionary—the keys are the names you use in the format string, the values are the corresponding views. Asa convenience, NSDictionaryOfVariableBindings creates a dictionary where the keys are the same asthe corresponding value’s variable name. The code to create the constraints thus becomes:

NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(button1, button2);

NSArray *constraints = [NSLayoutConstraintconstraintsWithVisualFormat:@"[button1]-[button2]"

options:0

metrics:nil

views:viewsDictionary];

The visual format language prefers good visualization over completeness of expressibility; there are thereforeconstraints that cannot be expressed in visual format syntax, although most of the constraints that are usefulin real user interfaces can be. One useful constraint that cannot be expressed is a fixed aspect ratio (for example,

Constraints Express Relationships Between ViewsCreate Constraints Programmatically Using an ASCII-Art Format String

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

9

Page 10: Auto Layout Pg(A definitive guide for IOS programmers)

imageView.width = 2 * imageView.height). To create such a constraint, you must useconstraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:. As anexample, you could create the [button1]-[button2] constraint using the following code.

[NSLayoutConstraint constraintWithItem:button1

attribute:NSLayoutAttributeRight

relatedBy:NSLayoutRelationEqual

toItem:button2

attribute:NSLayoutAttributeLeft

multiplier:1.0

constant:-12.0];

Constraints are Mostly ImmutableYou cannot change most of the properties of a constraint after you create it, but you can still change theconstant. There are two reasons for this:

● It’s algorithmically important. It is much more efficient to change the constant than to remove a constraintand add a new one.

● It leads to a natural way to implement operations such as dragging, which is exactly the case in whichperformance is most important.

Install ConstraintsTo make a constraint active, you must add it to a view. The view that holds the constraint must be an ancestorof the views the constraint involves, often the closest common ancestor. (This is in the existing NSView APIsense of the word ancestor , where a view is an ancestor of itself.) The constraint is interpreted in the coordinatesystem of that view.

Suppose you install [zoomableView1]-80-[zoomableView2] on the common ancestor of zoomableView1and zoomableView2.

Constraints Express Relationships Between ViewsConstraints are Mostly Immutable

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

10

Page 11: Auto Layout Pg(A definitive guide for IOS programmers)

The 80 is in the coordinate system of the container, which is what it looks like if you draw the constraint.

If the bounds transform of either of the zoomable views changes, the space between them remains fixed.

If the bounds transform in the container itself is changed, then the space scales too.

NSView provides a method—addConstraint:—to add a constraint, and methods to remove or inspectexisting constraints—removeConstraint: and constraints—as well as other related methods. NSViewalso provides a method, fittingSize, which is similar to the sizeToFit method of NSControl but forarbitrary views rather than for controls.

The fittingSize method returns the ideal size for the view considering only those constraints installed onthe receiver’s subtree together with a preference for the view to be as small as possible . The fitting size is not the“best” size for a view in a general sense—in the constraint-based system, a view’s “best” size if you considereverything has to be the size it currently has!

Auto Layout Degrades Gracefully with Unsatisfiable ConstraintsIt is a programming error to configure constraints that cannot be satisfied. Faced with unsatisfiable constraints,however, the Auto Layout system attempts to degrade gracefully.

1. The addConstraint: method (or the setConstant: method of NSLayoutConstraint) logs themutually unsatisfiable constraints and throws an exception.

The exception is appropriate because this is a programmer error.

2. The system catches the exception immediately.

Although adding a constraint that cannot be satisfied is a programmer error, it’s one that can readilyimagine occurring on a user’s computer, and one from which the system can recover more gracefully thancrashing the program. The exception is thrown so that you notice the problem, and caught because it’seasier to debug the constraint system if the system does still function.

Constraints Express Relationships Between ViewsAuto Layout Degrades Gracefully with Unsatisfiable Constraints

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

11

Page 12: Auto Layout Pg(A definitive guide for IOS programmers)

3. To allow layout to proceed, the system selects a constraint from among the mutually unsatisfiable set andlowers its priority from “required” to an internal value that is not required, but is higher priority thananything you can externally specify. The effect is that as things change going forward, this incorrectlybroken constraint is the first that the system attempts to satisfy. (Note: every constraint in the set will berequired to begin with, because otherwise it wouldn’t be causing a problem.)

2010-08-30 03:48:18.589 ak_runner[22206:110b] Unable to simultaneously satisfyconstraints:

(

"<NSLayoutConstraint: 0x40082d820 H:[NSButton:0x4004ea720'OK']-(20)-| (Names:'|':NSView:0x4004ea9a0 ) >",

"<NSLayoutConstraint: 0x400821b40 H:[NSButton:0x4004ea720'OK']-(29)-| (Names:'|':NSView:0x4004ea9a0 ) >"

)

Will attempt to recover by breaking constraint

<NSLayoutConstraint: 0x40082d820 H:[NSButton:0x4004ea720'OK']-(20)-| (Names:'|':NSView:0x4004ea9a0 ) >

Constraints Express Relationships Between ViewsAuto Layout Degrades Gracefully with Unsatisfiable Constraints

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

12

Page 13: Auto Layout Pg(A definitive guide for IOS programmers)

Visual Format SyntaxThe following are examples of constraints you can specify using the visual format. Note how the text visuallymatches the image.

Standard Space[button]-[textField]

Width Constraint[button(>=50)]

Connection to Superview|-50-[orchidBox]-50-|

Vertical LayoutV:[topField]-10-[bottomField]

Flush Views[maroonView][oceanView]

Priority[button(100@20)]

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

13

Visual Format Language

Page 14: Auto Layout Pg(A definitive guide for IOS programmers)

Equal Widths[button1(==button2)]

Multiple Predicates[flexibleButton(>=70,<=100)]

A Complete Line of Layout|-[find]-[findNext]-[findField(>=20)]-|

The notation prefers good visualization over completeness of expressibility. There are constraints that cannotbe expressed in visual format syntax, although most of the constraints that are useful in real user interfacescan be. One useful constraint that cannot be expressed is a fixed aspect ratio (for example, imageView.width= 2 * imageView.height). To create such a constraint, you must useconstraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:.

Visual Format String GrammarThe visual format string grammar is defined as follows (literals are shown in code font; e denotes the emptystring).

Replacement ruleSymbol

(<orientation>:)?

(<superview><connection>)?

<view>(<connection><view>)*

(<connection><superview>)?

<visualFormatString>

H|V<orientation>

|<superview>

Visual Format LanguageVisual Format String Grammar

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

14

Page 15: Auto Layout Pg(A definitive guide for IOS programmers)

Replacement ruleSymbol

[<viewName>(<predicateListWithParens>)?]<view>

e|-<predicateList>-|-<connection>

<simplePredicate>|<predicateListWithParens><predicateList>

<metricName>|<positiveNumber><simplePredicate>

(<predicate>(,<predicate>)*)<predicateListWithParens>

(<relation>)?(<objectOfPredicate>)(@<priority>)?<predicate>

==|<=|>=<relation>

<constant>|<viewName> (see note)<objectOfPredicate>

<metricName>|<number><priority>

<metricName>|<number><constant>

Parsed as a C identifier.

This must be a key mapping to an instance of NSView in the passedviews dictionary.

<viewName>

Parsed as a C identifier. This must be a key mapping to an instance ofNSNumber in the passed metrics dictionary.

<metricName>

As parsed by strtod_l, with the C locale.<number>

Note: For the objectOfPredicate production, a viewName is only acceptable if the subject ofthe predicate is the width or height of a view. That is, you can use [view1(==view2)] to specifythat view1 and view2 have the same width.

If you make a syntactic mistake, an exception is thrown with a diagnostic message. For example:

Expected ':' after 'V' to specify vertical arrangement

V|[backgroundBox]|

^

A predicate on a view's thickness must end with ')' and the view must end with ']'

|[whiteBox1][blackBox4(blackWidth][redBox]|

Visual Format LanguageVisual Format String Grammar

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

15

Page 16: Auto Layout Pg(A definitive guide for IOS programmers)

^

Unable to find view with name blackBox

|[whiteBox2][blackBox]

^

Unknown relation. Must be ==, >=, or <=

V:|[blackBox4(>30)]|

^

Visual Format LanguageVisual Format String Grammar

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

16

Page 17: Auto Layout Pg(A definitive guide for IOS programmers)

The Cocoa Auto Layout architecture distributes responsibility for layout between controllers and views. Ratherthan you writing a monolithic, omniscient, controller that calculates where views need to go for a givengeometry, views become more self-organizing. This approach reduces the complexity of controller logic, andmakes it easier to redesign views without requiring corresponding changes to the layout code.

A View Specifies its Intrinsic Content SizeLeaf-level views such as buttons typically know more about what size they should be than does the code thatis positioning them. This is communicated through the method intrinsicContentSize, which tells thelayout system that there is some content it doesn't natively understand in a view, and how large that contentintrinsically is. This method is overridden by view subclassers, and is called by the layout system. A typicalexample implementor would be a single line text field. The layout system does not understand text - it mustjust be told that there's something in the view, and that that something will require a certain amount of spaceif not clipped.

The layout system calls intrinsicContentSize, and will set up constraints that specify (1) that the opaquecontent should not be compressed or clipped, (2) that the view prefers to hug tightly to its content.

A view can implement intrinsicContentSize to return absolute values for its width and height, orNSViewNoInstrinsicMetric for either or both to indicate that it has no intrinsic metric for a given dimension.

Correct implementations of intrinsicContentSize are illustrated in the following examples.

● The intrinsic size for a push button is dictated by its title and image. A button’s intrinsicContentSizemethod should return a size with width and height that ensure that the title text is not clipped and thatall the image is visible.

● A horizontal slider, has an intrinsic height, but no intrinsic width—the slider artwork has no intrinsic bestwidth. A horizontal NSSlider object returns {NSViewNoInstrinsicMetric, <slider height>}.Any user of a slider will have to provide constraints that govern the width of the slider.

● A container, such as an instance of NSBox, has no intrinsic content size and returns {NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric }. Its subviews may have intrinsiccontent sizes, but the subviews’ content is not intrinsic to the box itself.

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

17

Dividing Responsibility Between Controllers andViews

Page 18: Auto Layout Pg(A definitive guide for IOS programmers)

A Controller Specifies How Important the Intrinsic Size IsAlthough a view specifies its intrinsic content size, the user of the view says how important it is. For example,by default, a push button:

● Strongly wants to hug its content in the vertical direction (buttons really ought to be their natural height)

● Weakly hugs its content horizontally (extra side padding between the title and the edge of the bezel isacceptable)

● Strongly resists compressing or clipping content in both directions

In the scope bar in Finder, however, the buttons only weakly resist compressing content in the horizontaldirection. (You can make the window small enough that buttons start truncating their contents.) Thus, Findershould lower the priority with which these buttons resist compressing content.

You set the hugging and compression priorities for a view usingsetContentHuggingPriority:forOrientation: andsetContentCompressionResistancePriority:forOrientation: respectively. By default, allAppKit-supplied views have a value of either NSLayoutPriorityDefaultHigh orNSLayoutPriorityDefaultLow.

Views Must Tell the Auto Layout System if Their Intrinsic Size ChangesAlthough the Auto Layout architecture reduces the burden on the implementer of a controller class, it mayslightly increase the burden on the implementer of a view class. If you implement a custom view class, youshould determine whether the view has an intrinsic size, and if so implement intrinsicContentSize toreturn a suitable value.

In addition, if a property of a view changes and that change affects the intrinsic content size, the view mustcall invalidateIntrinsicContentSize so that the layout system notices the change and can re-layout.In the implementation of your view class, you must ensure that if the value of any property upon which theintrinsic size depends changes, you invoke invalidateIntrinsicContentSize. For example, a text fieldcalls invalidateIntrinsicContentSize if the string value changes.

Layout Operates on Alignment Rectangles, Not FramesWhen considering layout, keep in mind that the frame of a control is less important than its visual extent. Asa result, ornaments like shadows and engraving lines should typically be ignored for the purposes of layout.Interface Builder has always done this.

Dividing Responsibility Between Controllers and ViewsA Controller Specifies How Important the Intrinsic Size Is

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

18

Page 19: Auto Layout Pg(A definitive guide for IOS programmers)

In the following example, the Aqua guide (the dashed blue line) aligns with the visual extent of the button,not with the button’s frame (the solid blue rectangle).

To allow layout based on the presentation of the content rather than the frame, views provide an alignmentrect, which is what the layout actually operates on. To determine whether your override is correct, you can setthe NSViewShowAlignmentRects default to YES to draw the alignment rects.

Views Indicate Baseline OffsetsFrequently you want to align controls by baseline. Although you have always been able to do this in InterfaceBuilder, it was not previously possible to do this at runtime. You can do so now usingNSLayoutAttributeBaseline in a constraint.

The methodbaselineOffsetFromBottom returns the distance betweenNSLayoutAttributeBottom andNSLayoutAttributeBaseline. This default return value for NSView is 0; the method is overridden bysubclasses for which it makes sense to do so.

Dividing Responsibility Between Controllers and ViewsViews Indicate Baseline Offsets

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

19

Page 20: Auto Layout Pg(A definitive guide for IOS programmers)

In an constraint-based layout system, the ability to debug effectively is clearly very important. Cocoa AutoLayout offers several features to help you find the source of errors.

● An exception is thrown if you configure constraints that cannot be satisfied.

See “Auto Layout Degrades Gracefully with Unsatisfiable Constraints” (page 11).

● Auto Layout provides runtime support for visualizing constraints.

Visualization may be useful both for finding a problematic constraint, and for detecting ambiguousconstraints.

● You can programmatically query the system to ask about ambiguous constraints.

You can send a view a hasAmbiguousLayout message to determine whether its frame is ambiguous,and visualize the ambiguity using exerciseAmbiguityInLayout (see “Handling Ambiguity” (page 22)).

● An instrument in Instruments helps you to understand changes over time.

The Auto Layout instrument may be included with the developer tools in the future, but is currentlyprovided as sample code in a template—see Cocoa Autolayout Demos .

Debugging WorkflowBroadly speaking, there are two phases to debugging a layout problem:

1. Map from “this view is in the wrong place” to “this constraint (or these constraints) is (are) incorrect.”

2. Map from “this constraint is incorrect” to “this code is incorrect.”

To debug a problem with Auto Layout

1. Identify the view with an incorrect frame.

It may be obvious which view has the problem; if it is not, you may find it helpful to use the NSViewmethod _subtreeDescription to create a textual description of the view hierarchy. (The_subtreeDescription method is not public API; it is, however, permissible to use for debuggingpurposes.)

2. If possible, reproduce the issue while running under the Auto Layout template in Instruments.

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

20

Debugging

Page 21: Auto Layout Pg(A definitive guide for IOS programmers)

(The Auto Layout instrument may be included with the developer tools in the future, but is currentlyprovided as sample code in a template—see Cocoa Autolayout Demos ).

3. Find the bad constraint or constraints.

To get the constraints affecting a particular view, useconstraintsAffectingLayoutForOrientation:. You can then inspect the constraints in thedebugger. They are printed using the visual format notation. If your views have identifiers (seeidentifier (NSView)), they print out using the identifier in the description, like this:

<NSLayoutConstraint: 0x400bef8e0H:[refreshSegmentedControl]-(8)-[selectViewSegmentedControl] (Names:refreshSegmentedControl:0x40048a600,selectViewSegmentedControl:0x400487cc0 ) >

otherwise the output looks like this:

<NSLayoutConstraint: 0x400cbf1c0H:[NSSegmentedControl:0x40048a600]-(8)-[NSSegmentedControl:0x400487cc0]>

4. If it’s not obvious which constraint is wrong at this point, visualize the constraints on screen by passingthe constraints to the window using visualizeConstraints:.

Here’s an example of visualizing the constraints affecting the find field’s horizontal layout:

When you click a constraint, it is printed in the console. In this way you can you can determine whichis which, and typically identify which is incorrect.

At this point you may be informed that the layout is ambiguous (see “Handling Ambiguity” (page 22)).

5. Find the code that’s wrong.

Sometimes, once you have identified the incorrect constraint, you will know what to do to fix it.

DebuggingDebugging Workflow

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

21

Page 22: Auto Layout Pg(A definitive guide for IOS programmers)

If this is not the case then, in Instruments, search for the pointer of the constraint (or some of itsdescription). This will show you interesting events in that constraint’s lifecycle—its creation, modification,installation into windows, and so on. For each of these you can see the backtrace where it happened.Find the stage at which things went awry, and look at the backtrace. This is the code with the problem.

Handling AmbiguityIn the above workflow, we assumed that the issue was an incorrect constraint. It is also possible that theproblem is due to a missing constraint. A layout is ambiguous if it is underspecified. For example, supposethe system consists of one constraint.

x + y == 100

Because there are an infinite number of solutions to this equation, the system is ambiguous (as opposed tounsatisfiable). You can resolve it by adding a second constraint such as:

x == y

In the normal course of solving layout, the system detects unsatisfiability but not ambiguity. (It is acomputationally expensive task to detect ambiguity in this system.) However, if you visualize constraints thesystem does check for ambiguity. If it detects an ambiguity, the visualizer presents an Exercise Ambiguitybutton. Figure 4-1 (page 22) shows the find panel after one of the constraints has been removed.

Figure 4-1 Constraint debugging window illustrating ambiguity

DebuggingHandling Ambiguity

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

22

Page 23: Auto Layout Pg(A definitive guide for IOS programmers)

Exercising ambiguity (clicking the button) makes your UI toggle between different states it could be in giventhe current set of constraints. Figure 4-2 (page 23) shows the layout of the find panel after clicking ExerciseAmbiguity. Notice the different layout.

Figure 4-2 Constraint debugging window illustrating alternate resolution of ambiguity

DebuggingHandling Ambiguity

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

23

Page 24: Auto Layout Pg(A definitive guide for IOS programmers)

In addition to the “display” pass Cocoa has always used, Cocoa Auto Layout adds two more passes that occurwhen rendering a window: updateConstraintsIfNeeded and layoutIfNeeded. These occur in order:update constraints, layout, display. If you invoke display manually, it invokes layout and layout invokesupdateConstraints.

You can think of the update constraints pass as a measurement pass that communicates changes in geometryto the layout system. For example, if you change the title of a button at some point the text has to be measured,and a constraint has to be set up that communicates that information into the layout system. The updateconstraints pass is bottom-up.

It is in the layout pass that the frames of views are updated. The layout pass is top-down.

These passes have parallel sets of methods:

InvokeDirectly

OverrideUpdate ConstraintsLayoutDisplay

Normallycalledautomaticallyby AppKit,but may becalled if youneed thingsto beup-to-dateright now.

No.updateConstraints-IfNeeded

(NSWindow)

layoutIfNeeded

(NSWindow)

displayIfNeeded

(NSWindow)

Perform pass atwindow level

Normallycalledautomaticallyby AppKit,but may becalled if youneed thingsto beup-to-dateright now.

No.updateConstraintsFor-SubtreeIfNeeded

(NSView)

layoutSubtree-IfNeeded

(NSView)

displayIfNeeded

(NSView)

Perform pass atview level

Sets things upand invokes theview overridablemethod on allviews in subtreethat are dirtywith respect tothe pass.

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

24

Core Layout Runtime

Page 25: Auto Layout Pg(A definitive guide for IOS programmers)

InvokeDirectly

OverrideUpdate ConstraintsLayoutDisplay

You shouldnot call thesemethodsdirectly.

Yes.updateConstraints

(NSView)

layout

(NSView)

drawRect:

(NSView)

View leveloverridablemethod

Subclassersshould overridethis method todo therequested workfor the receiver.Thisimplementationshould not dirtythe current orprevious passesor invoke laterpasses.

Yes, if/whennecessary.

No.needsUpdate-Constraints

(NSView)

setNeedsUpdate-Constraints:

(NSView)

needsLayout(NSView)

setNeedsLayout:(NSView)

needsDisplay(NSView)

setNeedsDisplay:(NSView)

Invalidation

Get / setmethods forinvalidation ofthe pass.

If you’re implementing a custom view, the most common methods to interact with are the view-level overridablemethods and the invalidation methods.

● You can override updateConstraints to perform deferred constraint setup. You invokesetNeedsUpdateConstraints: when you have set up you want to defer. This is particularly usefulwhen a nib file is loaded and properties are changing a lot—you won’t receive updateConstraintsuntil things have settled down.

● You should only override layout only if you want to do custom layout. If you do, then you also need toinvoke setNeedsLayout: when something that feeds into your custom layout changes.

To reiterate: you never need to call setNeedsLayout: unless you override layout. Based on changes toconstraints, the layout engine determines when layout is required.

A controller object is typically more concerned with the NSWindow and NSViewmethods that perform the pass.These uses are more rare, though still valid and needed on occasion.

Core Layout Runtime

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

25

Page 26: Auto Layout Pg(A definitive guide for IOS programmers)

● Perform the update constraints pass manually to make sure all constraints are up to date.

You might do this before introspecting a constraint to extract a metric.

● Perform the layout pass manually if you want to extract frames from views and make decisions based onthem. If you don’t make sure layout is up to date first, the frames won’t be meaningful.

An NSAlert object uses this as part of its layout. The constraint-based system doesn’t deal with flowedtext and line breaking any better (or worse) than springs and struts does. NSAlert sets up all its constraintsexcept for anything giving the height of the text fields. Then it calls layoutSubtreeIfNeeded. At thispoint the text fields have the correct width but not the correct height. It then uses NSTextFieldmethodsto find the appropriate height for the fields given their width, and adds the height constraints.

Core Layout Runtime

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

26

Page 27: Auto Layout Pg(A definitive guide for IOS programmers)

Views that are aware of Auto Layout can coexist in a window with views that are not. That is, an existing projectcan incrementally adopt Auto Layout features.

This works through the property translatesAutoresizingMaskIntoConstraints. When this propertyis YES, which it is by default, the autoresizing mask of a view is translated into constraints. For example, if aview is configured as in Figure 6-1 and translatesAutoresizingMaskIntoConstraints is YES, then theconstraints |-20-[button]-20-| and V:|-20-[button(20)] are added to the view’s superview. The neteffect is that unaware views behave as they did in versions of OS X prior to 10.7.

Figure 6-1 Button layout using springs and struts

If you move the button 15 points to the left (including by calling setFrame: at runtime), the new constraintswould be |-5-[button]-35-| and V:|-20-[button(20)].

For views that are aware of Auto Layout, in most circumstances you will wanttranslatesAutoresizingMaskIntoConstraints to be NO. This is because the constraints generated bytranslating the autoresizing mask are already sufficient to completely specify the frame of a view given itssuperview’s frame, which is generally too much. For example, this will prevent a button from automaticallyassuming its optimal width when its title is changed.

The principal circumstance in which you should not callsetTranslatesAutoresizingMaskIntoConstraints: is when you are not the person who specifies aview’s relation to its container. For example, an NSTableRowView instance is placed by NSTableView. Itmight do this by allowing the autoresizing mask to be translated into constraints, or it might not. This is aprivate implementation detail. Other views on which you should not callsetTranslatesAutoresizingMaskIntoConstraints: include an NSTableCellView, a subview of

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

27

Adopting Auto Layout

Page 28: Auto Layout Pg(A definitive guide for IOS programmers)

NSSplitView, an NSTabViewItem’s view, or the content view of an NSPopover, NSWindow, or NSBox. Forthose familiar with classic Cocoa layout: If you would not call setAutoresizingMask: on a view in classicstyle, you should not call setTranslatesAutoresizingMaskIntoConstraints: under Auto Layout.

If you have a view that does its own custom layout by calling setFrame:, your existing code should work.Just don’t call setTranslatesAutoresizingMaskIntoConstraints: with the argument NO on viewsthat you place manually.

To provide additional compatibility, the entire constraint-based layout system is not active at all until youinstall a constraint on a view. Typically this is not something you should be concerned with, but if your previouslayout was delicate in that you had problems you fixed by figuring out in what order the framework calledmethods, you may find that these problems are back under constraint-based layout. Hopefully in most casesthe easiest solution will be to adopt constraint-based layout for the affected views. If you’re a framework authorproviding custom views and want to avoid engaging constraint-based layout in a window, you can do anynecessary work in updateConstraints. This method is not called until constraint-based layout is engaged.Furthermore, one of the purposes of updateConstraints is that it has a well-defined timing, similar toawakeFromNib, so you may find your problems are easier to resolve under Auto Layout.

There is an edge case to be aware of. When you implement a view, you might implement all your constraintsetup in a custom updateConstraints method. However, because the constraint based system engageslazily, if nothing installs any constraint, your updateConstraints method will never be invoked. To avoidthis problem, you can override requiresConstraintBasedLayout to return YES to signal that your viewneeds the window to use constraint based layout.

Adopting Auto Layout

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

28

Page 29: Auto Layout Pg(A definitive guide for IOS programmers)

This table describes the changes to Cocoa Auto Layout Guide .

NotesDate

Added to iOS Library. Added links to WWDC videos.2012-09-19

Corrected minor code error.2012-02-16

New document that describes the constraint-based system for laying outuser interface elements.

2011-07-06

2012-09-19 | © 2012 Apple Inc. All Rights Reserved.

29

Document Revision History

Page 30: Auto Layout Pg(A definitive guide for IOS programmers)

Apple Inc.© 2012 Apple Inc.All rights reserved.

No part of this publication may be reproduced,stored in a retrieval system, or transmitted, in anyform or by any means, mechanical, electronic,photocopying, recording, or otherwise, withoutprior written permission of Apple Inc., with thefollowing exceptions: Any person is herebyauthorized to store documentation on a singlecomputer for personal use only and to printcopies of documentation for personal useprovided that the documentation containsApple’s copyright notice.

No licenses, express or implied, are granted withrespect to any of the technology described in thisdocument. Apple retains all intellectual propertyrights associated with the technology describedin this document. This document is intended toassist application developers to developapplications only for Apple-labeled computers.

Apple Inc.1 Infinite LoopCupertino, CA 95014408-996-1010

Apple, the Apple logo, Aqua, Cocoa, Finder,Instruments, and OS X are trademarks of AppleInc., registered in the U.S. and other countries.

iOS is a trademark or registered trademark ofCisco in the U.S. and other countries and is usedunder license.

Even though Apple has reviewed this document,APPLE MAKES NO WARRANTY OR REPRESENTATION,EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THISDOCUMENT, ITS QUALITY, ACCURACY,MERCHANTABILITY, OR FITNESS FOR A PARTICULARPURPOSE. AS A RESULT, THIS DOCUMENT IS PROVIDED“AS IS,” AND YOU, THE READER, ARE ASSUMING THEENTIRE RISK AS TO ITS QUALITY AND ACCURACY.

IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT,INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIALDAMAGES RESULTING FROM ANY DEFECT ORINACCURACY IN THIS DOCUMENT, even if advised ofthe possibility of such damages.

THE WARRANTY AND REMEDIES SET FORTH ABOVEARE EXCLUSIVE AND IN LIEU OF ALL OTHERS, ORALOR WRITTEN, EXPRESS OR IMPLIED. No Apple dealer,agent, or employee is authorized to make anymodification, extension, or addition to this warranty.

Some states do not allow the exclusion or limitationof implied warranties or liability for incidental orconsequential damages, so the above limitation orexclusion may not apply to you. This warranty givesyou specific legal rights, and you may also have otherrights which vary from state to state.