autolayout primer

48
Autolayout Primer Internal presentation @ iCapps, 2013-12-04

Upload: inferis

Post on 09-May-2015

1.487 views

Category:

Technology


0 download

DESCRIPTION

This is a presentation I gave at an internal meeting at iCapps on 20131204.

TRANSCRIPT

Page 1: Autolayout primer

Autolayout PrimerInternal presentation @ iCapps, 2013-12-04

Page 2: Autolayout primer

Introduction

Page 3: Autolayout primer

Tom Adriaenssen

Page 4: Autolayout primer

I love...

‣ ... my wife ‣ ... my 4 kids ‣ ... to code ‣ ... to play a game of squash ‣ ... good beer

Page 5: Autolayout primer

I open sourced...... some code:

‣ IIViewDeckController: “An implementation of the sliding functionality found in the Path 2.0 or Facebook iOS apps.”

‣ IIDateExtensions

‣ IIPopoverStatusItem

See: http://github.com/inferis

Page 6: Autolayout primer

I made...

... some apps:

Butane Drash

Hi, @10to1!http://getbutane.com http://dra.sh

Page 7: Autolayout primer

Agenda

Page 8: Autolayout primer

Agenda

‣ What is Autolayout? ‣ What is a constraint? ‣ Autolayout in Xcode designer ‣ Autolayout in code

Page 9: Autolayout primer

Autolayout

Page 10: Autolayout primer

What is Autolayout?

Auto%Layout%is%a%system%that%lets%you%lay%out%your%app’s%user%interface%by%creating%a%mathematical%description%of%the%relationships%between%the%elements.%%

According to the Apple Docs:

‣ Keywords: ‣ mathematical ‣ relationships

‣ Eh? ‣ Developer defines constraints on/between elements ‣ constraints translate into mathematical functions ‣ UIKit/Appkit tries to solve these functions

Page 11: Autolayout primer

What is Autolayout?‣ Correctly using autolayout requires you to change thinking

‣ Autolayout works in a different way than what you were used to

‣ Don't go calculating frames anymore ‣ Define how an element should behave according to it's

peers: ‣ parent ‣ siblings

‣ Don't think in absolute terms, but think in relational terms ‣ Think flexible: it's not because an element has a certain

size at one point, it will have the same size at another point

Page 12: Autolayout primer

Constraints

Page 13: Autolayout primer

Constrainta%mathematical%representation%of%a%human:expressable%statement%

"the left edge should be 20pt of the superviews left edge"

view.left = (superview.left + 20)

y = m * x + c

(y%=%attribute1%=%view.left)%(x%=%attribute2%=%superview.left)%

(m%=%multiplier%=%1)%(c%=%constant%=%20)

Page 14: Autolayout primer

//%firstItem.firstAttribute%{==,<=,>=}%secondItem.secondAttribute%*%multiplier%+%constant%!@property%(readonly,%assign)%id%firstItem;%@property%(readonly)%NSLayoutAttribute%firstAttribute;%@property%(readonly)%NSLayoutRelation%relation;%@property%(readonly,%assign)%id%secondItem;%@property%(readonly)%NSLayoutAttribute%secondAttribute;%@property%(readonly)%CGFloat%multiplier;%!@property%CGFloat%constant;

Constraint‣ two items with an attribute ‣ constant ‣ relation ‣ multiplier ‣ priority level

//%firstItem.firstAttribute%{==,<=,>=}%secondItem.secondAttribute%*%multiplier%+%constant%!@property%(readonly,%assign)%id%firstItem;%@property%(readonly)%NSLayoutAttribute%firstAttribute;%@property%(readonly)%NSLayoutRelation%relation;%@property%(readonly,%assign)%id%secondItem;%@property%(readonly)%NSLayoutAttribute%secondAttribute;%@property%(readonly)%CGFloat%multiplier;%!@property%CGFloat%constant;

Page 15: Autolayout primer

Attribute?‣ left ‣ right ‣ top ‣ bottom ‣ leading ~ left or right depending on language settings ‣ trailing ~ right or left depending on language settings ‣ width ‣ height ‣ centerX ‣ centerY ‣ baseline

Page 16: Autolayout primer

Constant?‣ physical size or offset

Page 17: Autolayout primer

Multiplier?‣ Apply modifier to attribute of source item

‣ Cannot be set using the designer ‣ Can be set in code

Page 18: Autolayout primer

Relation?‣ equal ‣ less than or equal ‣ greater than or equal !

‣ if you want just "less than" or "greater than", adjust the constant

Page 19: Autolayout primer

Priority‣ constraints with higher priority are satisfied before

constraints with lower priority ‣ Default = UILayoutPriorityRequired (1000) ‣ Other predefined priorities

‣ UILayoutPriorityRequired = 1000 ‣ UILayoutPriorityDefaultHigh = 750

‣ Default content compression priority

‣ UILayoutPriorityDefaultLow = 250 ‣ Default content hugging priority

‣ UILayoutPriorityFittingSizeLevel = 50 ‣ You can use any integer value between 0-1000

Page 20: Autolayout primer

Pitfalls‣ constraints are cumulative ‣ constraints do not override each other

‣ adding a second width constraint does not remove or override a previous one

‣ remove first one manually ‣ constraints can cross view hierarchy

‣ add constraint from view to superview of superview

‣ only if scope of view hierarchy uses autolayout! (no custom framesetting)

Page 21: Autolayout primer

Intrisic Content Size‣ applicable to leaf views (views with no subviews) ‣ view knows what size it wants to be (eg UIButton) ‣ autolayout will size view to its intristic content size if no

constraints control the width/height

:%(CGSize)intrinsicContentSize;

Returns%the%natural%size%for%the%receiving%view,%considering%only%properties%of%the%view%itself.%

‣ You can override this method in a subclass to change the default behavior

‣ return UIViewNoIntrinsicMetric when there's no intristic size defined for an axis

Page 22: Autolayout primer

Compression resistance & Content hugging‣ Content Compression resistance?

‣ defines how the view's frame resist compressing it's content

‣ Content hugging? ‣ defines how the view's frame should hug it's

content

Page 23: Autolayout primer

Compression resistance & Content huggingSay you've got button like this: % |[%%%%%%%Click%Me%%%%%%]|%

and you've pinned the edges to a larger superview with priority 500. !Then, if hugging priority > 500 it'll look like this: % |[Click%Me]%%%%%%%%%%%%%|%

If hugging priority < 500 it'll look like this: % |[%%%%%%%Click%Me%%%%%%]|%

!If the superview now shrinks and if the compression resistance priority > 500, it'll look like this % |[Click%|Me]%

else if compression resistance priority < 500, it could look like this: % |[Cli..]|

Page 24: Autolayout primer

Autolayout in Xcode designer

Page 25: Autolayout primer

Demo

Page 26: Autolayout primer

Autolayout in code

Page 27: Autolayout primer

Autolayout in code: 3 options‣ Write constraints manually

‣ HEAD WILL EXPLODE ‣ Use visual format

‣ HEAD WILL EXPLODE MOAR ‣ Use UIView+AutoLayout Cocoapod

‣ Provides descriptive methods creating constraints

‣ Still verbose but quite readable ‣ Best of both worlds

Page 28: Autolayout primer

Autolayout in code‣ Important note when creating constraints in code ‣ If you create a view manually, use: !

!

‣ if you don’t, you’ll get a lot of constraint errors!

view%=%[UIView%new];%view.translatesAutoresizingMaskIntoConstraints%=%NO;

Page 29: Autolayout primer

UIView+AutoLayout‣ Available as a CocoaPod

‣ Implements a category on UIView. ‣ Easy creation of 1 or more NSLayoutConstraints.

‣ Some methods return 1 constraint, some an NSArray containing constraints

‣ Does not add constraints, just creates them ‣ you need to add them yourself

:(void)addConstraint:(NSLayoutConstraint%*)constraint;%:(void)addConstraints:(NSArray%*)constraints;

Page 30: Autolayout primer

UIView+AutoLayout

‣ Don't use: translatesAutoresizingMaskIntoConstraints !% view%=%[UIView%newAutoLayoutView];%% //%or%% view%=%[[UIView%alloc]%initForAutoLayout];

Creating an autolayouted view

Page 31: Autolayout primer

UIView+AutoLayout

:%(NSLayoutConstraint%*)autoPinEdgeToSuperviewEdge:(ALEdge)edge%withInset:(CGFloat)inset;%

‣ Pins the given edge of the view to the same edge of the superview with an inset.

!:%(NSLayoutConstraint%*)autoPinEdgeToSuperviewEdge:(ALEdge)edge%withInset:(CGFloat)inset%relation:(NSLayoutRelation)relation;%

‣ Pins the given edge of the view to the same edge of the superview with an inset as a maximum or minimum.

!:%(NSArray%*)autoPinEdgesToSuperviewEdgesWithInsets:(UIEdgeInsets)insets;%

‣ Pins the edges of the view to the edges of its superview with the given edge insets.

Pin to superview edges

Page 32: Autolayout primer

UIView+AutoLayout

:%(NSLayoutConstraint%*)autoPinEdge:(ALEdge)edge%%%%%%%%%%%%%%%%toPositionInSuperview:(CGFloat)value;%

‣ Pins the given edge of the view to a fixed position (X or Y value, depending on edge) in the superview.

Pin at point in superview

Page 33: Autolayout primer

UIView+AutoLayout

:%(NSArray%*)autoCenterInSuperview;%

‣ Centers the view in its superview. !:%(NSLayoutConstraint%*)autoCenterInSuperviewAlongAxis:(ALAxis)axis;%

‣ Centers the view along the given axis (horizontal or vertical) within its superview. !:%(NSLayoutConstraint%*)autoPinCenterAxis:(ALAxis)axis%%% % % % %%%toPositionInSuperview:(CGFloat)value;%

‣ Pins the given center axis of the view to a fixed position (X or Y value, depending on axis) in the superview.

Centering in superview

Page 34: Autolayout primer

UIView+AutoLayout

:%(NSLayoutConstraint%*)autoPinEdge:(ALEdge)edge%toEdge:(ALEdge)toEdge%ofView:(UIView%*)peerView;%

‣ Pins an edge of the view to a given edge of another view. !:%(NSLayoutConstraint%*)autoPinEdge:(ALEdge)edge%toEdge:(ALEdge)toEdge%ofView:(UIView%*)peerView%withOffset:(CGFloat)offset;%

‣ Pins an edge of the view to a given edge of another view with an offset. !:%(NSLayoutConstraint%*)autoPinEdge:(ALEdge)edge%toEdge:(ALEdge)toEdge%ofView:(UIView%*)peerView%withOffset:(CGFloat)offset%relation:(NSLayoutRelation)relation;%

‣ Pins an edge of the view to a given edge of another view with an offset as a maximum or minimum.

Pin to other views

Page 35: Autolayout primer

UIView+AutoLayout

:%(NSLayoutConstraint%*)autoAlignAxis:(ALAxis)axis%%%%%%%%%%%%%%%%%%%%%%%toSameAxisOfView:(UIView%*)peerView;%

‣ Aligns an axis of the view to the same axis of another view. !:%(NSLayoutConstraint%*)autoAlignAxis:(ALAxis)axis%%%%%%%%%%%%%%%%%%%%%%%toSameAxisOfView:(UIView%*)peerView%%%% % % % % %%%%%%withOffset:(CGFloat)offset;%

‣ Aligns an axis of the view to the same axis of another view with an offset.

Aligning views

Page 36: Autolayout primer

UIView+AutoLayout

:%(NSArray%*)autoSetDimensionsToSize:(CGSize)size;%

‣ Sets the view to a specific size. !:%(NSLayoutConstraint%*)autoSetDimension:(ALDimension)dimension%%% % % % % % % % %toSize:(CGFloat)size;%

‣ Sets the given dimension of the view to a specific size. !:%(NSLayoutConstraint%*)autoSetDimension:(ALDimension)dimension%%%%% % % % % % % % %toSize:(CGFloat)size%%% % % % % % % %%%relation:(NSLayoutRelation)relation;%

‣ Sets the given dimension of the view to a specific size as a maximum or minimum.

View dimensions

Page 37: Autolayout primer

UIView+AutoLayout

:%(NSLayoutConstraint%*)autoMatchDimension:(ALDimension)dimension%toDimension:(ALDimension)toDimension%ofView:(UIView%*)peerView;%

‣ Matches a dimension of the view to a given dimension of another view. :%(NSLayoutConstraint%*)autoMatchDimension:(ALDimension)dimension%toDimension:(ALDimension)toDimension%ofView:(UIView%*)peerView%withOffset:(CGFloat)offset;%

‣ Matches a dimension of the view to a given dimension of another view with an offset. :%(NSLayoutConstraint%*)autoMatchDimension:(ALDimension)dimension%toDimension:(ALDimension)toDimension%ofView:(UIView%*)peerView%withOffset:(CGFloat)offset%relation:(NSLayoutRelation)relation;%

‣ Matches a dimension of the view to a given dimension of another view with an offset as a maximum or minimum.

:%(NSLayoutConstraint%*)autoMatchDimension:(ALDimension)dimension%toDimension:(ALDimension)toDimension%ofView:(UIView%*)peerView%withMultiplier:(CGFloat)multiplier;%

‣ Matches a dimension of the view to a multiple of a given dimension of another view. :%(NSLayoutConstraint%*)autoMatchDimension:(ALDimension)dimension%toDimension:(ALDimension)toDimension%ofView:(UIView%*)peerView%withMultiplier:(CGFloat)multiplier%relation:(NSLayoutRelation)relation;%

‣ Matches a dimension of the view to a multiple of a given dimension of another view as a maximum or minimum.

View dimension matching

Page 38: Autolayout primer

UIView+AutoLayout

+%(void)autoSetPriority:(UILayoutPriority)priority%%%%%%%%%%%forConstraints:(ALConstraintsBlock)block;%

‣ Sets the constraint priority to the given value for all constraints created using the UIView+AutoLayout category API within the given constraints block.

‣ NOTE: This method will have no effect (and will NOT set the priority) on constraints created or added using the SDK directly within the block!

‣ Use the auto… methods of UIView+AutoLayout

Priorities

Page 39: Autolayout primer

UIView+AutoLayout

:%(void)autoRemoveConstraintsAffectingView;%

‣ Removes all explicit constraints that affect the view. :%(void)autoRemoveConstraintsAffectingViewAndSubviews;%

‣ Recursively removes all explicit constraints that affect the view and its subviews. Additional%methods%if%you%do%want%to%remove%the%:%(void)autoRemoveConstraintsAffectingViewIncludingImplicitConstraints:(BOOL)shouldRemoveImplicitConstraints;%

‣ Removes all constraints that affect the view, optionally including implicit constraints.

:(void)autoRemoveConstraintsAffectingViewAndSubviewsIncludingImplicitConstraints:(BOOL)shouldRemoveImplicitConstraints;%

‣ Recursively removes all constraints from the view and its subviews, optionally including implicit constraints.

Removal of constraints

Page 40: Autolayout primer

UIView+AutoLayoutRemoval of constraints

‣ A little bit of a warning when removing constraints: ‣ The constraint solving engine is not optimised for

the removal of constraints ‣ Removing a lot of constraints can have serious

impact on performance ‣ Use with care and in small quantities

‣ You can change the priority of a constraint to “disable” it (but you have to remember the original value to reenable it)

Page 41: Autolayout primer

UIView+AutoLayout

‣ category on NSArray doing the same for groups of views

‣ category on NSLayoutConstraint to remove a constraint from the view it's attached to

Other stuff

Page 42: Autolayout primer

Protips‣ Where to add which constraints?

‣ When constraints only apply to 1 view (eg setting dimensions) ‣ create on view ‣ add to view

‣ When constraints apply to more than 1 view eg pin one view to another ‣ create on target view ‣ add to common superview of both views (usually the

same)

Page 43: Autolayout primer

Protips ‣ Check for autotranslated autoresizing constraints ‣ don’t forget translatesAutoresizingMaskIntoConstraints

‣ Display the view hierarchy from the root to find where things go wrong ‣ errors don’t provide any context !

‣ look for address of view giving errors, and then you’ll get an idea of what context the error is happing in

po%[[[[UIApplication%sharedApplication]%windows]%objectAtIndex:0]%recursiveDescription]

Page 44: Autolayout primer

Protips‣ Don’t assume a view has a fixed size

‣ (unless you give it a size constraint)

‣ initWithFrame: not really useful anymore ‣ Don’t use frame/bounds calculations in constraints

‣ exception: in layoutSubViews

‣ Try to minimalise the number of constraints ‣ solving takes time ‣ more constraints, more complex

Page 45: Autolayout primer

Protips‣ animating constraints

‣ set constraints outside animation block ‣ call layoutIfNeeded in animation ‣ Make sure you do this on the correct “top level

view” otherwise nothing will animate!

self.offsetConstraint.constant%=%[self%calculateOffset];%[UIView%animationWithDuration:0.3%animations:^{%% [self.view%layoutIfNeeded];%}];

Page 46: Autolayout primer

Protips‣ when changing content:

‣ don’t forget to update constraints ‣ call setNeedsUpdateConstraints

‣ let the system decide when to update

‣ or updateConstraintsIfNeeded ‣ immediate action

‣ only needed when your constraint change might affect other constraints

‣ don’t forget to relayout your views ‣ call setNeedsLayout ‣ or layoutIfNeeded

Page 47: Autolayout primer

Useful References‣ Apple’s autolayout documentation: ‣ reference: https://developer.apple.com/library/ios/

documentation/userexperience/conceptual/AutolayoutPG/Introduction/Introduction.html

‣ Martin Pilkington’s iOSDevUK2013 slides on autolayout solving ‣ http://www.iosdevuk.com/storage/talks2013/

MartinPilkington.pdf ‣ UIView+AutoLayout ‣ https://github.com/smileyborg/UIView-AutoLayout

Page 48: Autolayout primer

Thanks for listening.

Twitter: @inferis App.Net: @inferis E-mail: [email protected] vCard: http://inferis.org

Questions? Contact me: