Prac%cal'Autolayout 
CocoaHeadsBE+Nov+2014 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 1
Me 
• Tom$Adriaenssen 
• Lead&iOS&Dev&at& 
• @Inferis&(Twi6er,&app.net) 
• h6p://inferis.org 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 2
Prac%cal'Autolayout 
• Libraries 
• Upda,ng/Constraints 
• Intrins,c/Content/Size 
• Alignment/Rects 
• Baseline/alignment 
• Priori,es 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 3
Libraries 
• !"provided*APIs*are*cumbersome 
• Wrapper*libraries*make*your*life*easier 
• declara9ve*vs*impera9ve 
• more*descrip9ve 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 4
Libraries 
• PureLayout+(Objec've)C,,CocoaPod) 
• FLKLayout+(Objec've)C,,CocoaPod) 
• Masonry+(Objec've)C,,CocoaPod) 
• KeepLayout+(Objec've)C,,CocoaPod) 
• Lyt+(Objec've)C,,CocoaPod) 
• Cartography+(Swi5) 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 5
PureLayout 
• Defines'categories'(auto*)'on'UIView/ 
NSView'&'NSArray 
• Code'only,'no'stringAbased'DSL 
• Support'for'prioriFes'via'blocks 
• Originally'UIView+AutoLayout 
• Github:'hNps://github.com/smileyborg/ 
PureLayout 
• CocoaPod: 
pod 'PureLayout' 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 6
PureLayout 
[self.blueView autoCenterInSuperview]; 
[self.blueView autoSetDimensionsToSize:CGSizeMake(50.0, 50.0)]; 
s// Red view is positioned at the bottom right corner of the blue view, with the same width, and a height of 40 pt 
[self.redView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.blueView]; 
[self.redView autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:self.blueView]; 
[self.redView autoMatchDimension:ALDimensionWidth toDimension:ALDimensionWidth ofView:self.blueView]; 
[self.redView autoSetDimension:ALDimensionHeight toSize:40.0]; 
[@[self.redView, self.yellowView] autoSetViewsDimension:ALDimensionHeight toSize:50.0]; 
[@[self.blueView, self.greenView] autoSetViewsDimension:ALDimensionHeight toSize:70.0]; 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 7
FLKAutoLayout 
• Category*on*UIView 
• uses*predicates*for*priori5es*and* 
rela5ons 
• Code*&*string9based*DSL*(predicates) 
• Github:*hDps://github.com/ 
floriankugler/FLKAutoLayout 
• CocoaPod: 
pod 'FLKAutoLayout' 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 8
FLKAutoLayout 
// align the first label with its superview 
[labels[0] alignTop:@"20" leading:@"20" toView:labels[0].superview]; 
// give it a minimum width of 200 and a maximum width of 300 
[labels[0] constrainWidth:@">=200,<=300"]; 
// now constrain all labels to this size 
[UIView alignLeadingAndTrailingEdgesOfViews:labels]; 
// space the labels out vertically with 10 points in between 
[UIView spaceOutViewsVertically:labels predicate:@"10"]; 
// now let's take care of the text fields. 
// the first one has a fixed space of 20 to its label 
[textFields[0] constrainLeadingSpaceToView:labels[0] predicate:@"20"]; 
// constrain the right edge to its superview with 20 points padding 
[textFields[0] alignTrailingEdgeWithView:textFields[0].superview predicate:@"20"]; 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 9
Masonry 
• Custom(layout(DSL 
• define(constraints(in( 
mas_makeConstraints:(block 
• Code(only,(no(string:based(DSL 
• Github:(h>ps://github.com/Masonry/ 
Masonry 
• CocoaPod: 
pod 'Masonry' 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 10
Masonry 
UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10); 
[view1 mas_makeConstraints:^(MASConstraintMaker *make) { 
make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler 
make.left.equalTo(superview.mas_left).with.offset(padding.left); 
make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom); 
make.right.equalTo(superview.mas_right).with.offset(-padding.right); 
}]; 
// or even shorter 
[view1 mas_makeConstraints:^(MASConstraintMaker *make) { 
make.edges.equalTo(superview).with.insets(padding); 
}]; 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 11
KeepLayout 
• use%keep*%a*ributes%on%UIView/NSView% 
to%define%layout 
• Also%works%on%arrays%of%views 
• Code%only,%no%stringBbased%DSL 
• Github:%h*ps://github.com/iMarLnKiss/ 
KeepLayout 
• CocoaPod: 
pod 'KeepLayout' 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 12
KeepLayout 
// aligns are the same regardless of order 
viewOne.keepLeftAlign(viewTwo) == viewTwo.keepLeftAlign(viewOne) 
// left offset from 1 to 2 is right offset from 2 to 1 
viewOne.keepLeftOffset(viewTwo) == viewTwo.keepRightOffset(viewOne) 
// array attributes 
NSArray *views = @[ viewOne, viewTwo, viewThree ]; 
[views keepWidthsEqual]; 
[views keepHorizontalOffsets:20]; 
[views keepTopAligned]; 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 13
Lyt 
• Defines'categories'(lyt_*)'on'UIView/ 
NSView 
• Code'only,'no'string?based'DSL 
• No'support'for'prioriEes'or'relaEons 
• Github:'hIps://github.com/robotmedia/ 
Lyt 
• CocoaPod: 
pod 'Lyt' 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 14
Lyt 
[view lyt_centerInParent]; 
// instead of 
NSLayoutConstraint *centerXConstraint = [NSLayoutConstraint constraintWithItem:view 
attribute:NSLayoutAttributeCenterX 
relatedBy:NSLayoutRelationEqual 
toItem:view.superview 
attribute:NSLayoutAttributeCenterX 
multiplier:1.0 
constant:0]; 
NSLayoutConstraint *centerYConstraint = [NSLayoutConstraint constraintWithItem:view 
attribute:NSLayoutAttributeCenterY 
relatedBy:NSLayoutRelationEqual 
toItem:view.superview 
attribute:NSLayoutAttributeCenterY 
multiplier:1.0 
constant:0]; 
[view.superview addConstraints:@[centerXConstraint, centerYConstraint]]; 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 15
Cartography 
• Swi%! 
• Leverages.custom.operators.for.a. 
declara8ve.API 
• Code.only 
• Github:.hCps://github.com/robb/ 
Cartography 
• No.CocoaPod.yet 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 16
Cartography 
layout(view1, view2) { view1, view2 in 
view1.width == (view1.superview!.width - 50) * 0.5 
view2.width == view1.width - 50 
view1.height == 40 
view2.height == view1.height 
view1.centerX == view1.superview!.centerX 
view2.centerX == view1.centerX 
view1.top >= view1.superview!.top + 20 
view2.top == view1.bottom + 20 
} 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 17
Libraries 
Considera*ons 
• does&the&library&give&you&access&to&the&created&constraints&for& 
modifica7ons 
• do&you&prefer&string&based&DSLs,&code&only&or&a&mix? 
• mostly&useful&in&larger&projects&where&you&have&to&manually& 
create&constraints 
• for&simple&cases/projects&the&na7ve&APIs&might&do&fine 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 18
Upda%ng(Constraints 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 19
Upda%ng(Constraints 
• Don't"update"constraints"all"over"the"place 
• "update"="add"/"delete 
• changing"constants"is"no"problem 
• use"updateConstraints"or"updateViewConstraints 
• you"can"create"constraints"on"beforehand,"but"add"or"remove" 
them"in"updateConstraints 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 20
Upda%ng(Constraints 
Example 
AutoLayoutAnimation.xcodeproj 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 21
Intrins'c)Content)Size 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 22
Intrins'c)Content)Size 
func intrinsicContentSize() -> CGSize 
• only&for&"leaf"&views 
• tells&the&layout&system&that&there&is&some&content&it&doesn’t& 
na7vely&understand&in&a&view 
• provides&to&the&layout&system&the&intrinsic&size&of&that&content 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 23
Intrins'c)Content)Size 
• return'UIViewNoIntrinsicMetric'if'you'don't'know'the'size' 
for'an'axis 
• when'content'changes'the'intrins7c'content'size,'call' 
invalidateIntrinsicContentSize() 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 24
Intrins'c)Content)Size 
• you%can%use%constraints%to%provide%an%intrins1c%content%size%for% 
containers 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 25
Intrins'c)Content)Size 
Example 
IntrinsticContentSize.xcodeproj 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 26
Alignment)Rects 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 27
Alignment)Rects 
• Autolayout)does)not)work)on)frames,)but)on)alignment)rects 
• For)most)views,)these)are)the)same)by)default 
• a)powerful)tool)to)decouple)a)view’s)layout)alignment)edges)from) 
its)visual)appearance 
• consider: 
• intrinis>c)content)size)should)be)based)of)alignment)rects,)not) 
frames 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 28
Alignment)Rects 
• bu$on'with'ornaments'(eg'badge)'▶️'larger'alignment'rect 
• align'to'smaller'view'content'▶️'smaller'alignment'rect 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 29
Alignment)Rects 
Example 
AutoLayoutAlignmentRects.xcodeproj 
AlignmentRectExamples.xcodeproj 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 30
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 31
Baseline(alignment 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 32
Baseline(alignment 
func viewForBaselineLayout() -> UIView? 
• by$default,$AutoLayout$aligns$view$by$baseline$using$the$bo7om$ 
of$the$view 
• can$specify$any$child$view$of$view 
• autolayout$will$use$this$view$for$baseline$aligment 
• view$aligned$on$bo7om$of$view$returned$by$this$method 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 33
Baseline(alignment 
• viewForBaselineLayout"works"only"on"iOS 
• for"OSX"use"baselineOffsetFromBottom: 
var baselineOffsetFromBottom: CGFloat { get } 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 34
Baseline(alignment 
Some%issues 
• dynamically*changing*this*view*is*not*possible 
• have*to*remove*and*re6add*a*baseline*constraint 
• buggy 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 35
Baseline(alignment 
Example 
AutolayoutBaselineAlignment.xcodeproj 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 36
Priori%es 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 37
Priori%es 
• Using'priori+es'is'the'key'in'powerful'AutoLayout 
• Define'mul+ple'constraints'on'the'same'a<ribute'with'different' 
priori+es 
• if'possible'all'will'be'matched,'otherwise'those'with'lower' 
priori+es'are'dropped 
• use'in'combina+on'with'hugging'priority'and'compression' 
priority 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 38
Pi#alls'&'Tips 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 39
Pi#alls 
• constraints*are*cumula/ve 
• constraints*do*not*override*each*other 
• adding*a*second*width*constraint*does*not*remove*or*override* 
a*previous*one 
• remove*first*one*manually 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 40
Pi#alls 
• be$careful$with$default$priori2es 
• eg:$pinning$with$insets$7>$what$if$external$view$is$too$small$to$ 
fit$insets? 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 41
Tips 
• constraints*can*cross*view*hierarchy 
• add*constraint*from*view*to*superview*of*superview 
• only*if*scope*of*view*hierarchy*uses*autolayout!*(no*custom* 
framese8ng*inbetween) 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 42
Tips 
Autoresizing,masks 
• when&crea*ng&views&in&code,&set& 
translatesAutoresizingMaskIntoConstraints&to&NO. 
• UIKit&will&not&add&equivalent&constraints&for&the& 
autoresizingMask&of&the&view 
• these&(very&likely)&will&clash&with&your&own&constraints 
• or,&clear&autoresizing&mask 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 43
Tips 
Think&rela+onal,&not&absolute 
• some&mes'absolute'values'are'necessary 
• most'of'the'&me'you'want'views'to'size'according'to'content 
• content'is'(probably)'not'fixed 
• views'are'o>en'not'the'sizes'you'expect'(iPhone6/6+!) 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 44
Tips 
• Autolayout)is)not)a)holy)grail 
• Autolayout)seems)"easy")but)is)tricky)to)get)right 
• frame)based)layout)is)o8en)faster)and)more)finetuned 
• when)doing)frame)based)layout,)do)it)correctly 
• in)layoutSubviews 
• don't)confuse)bounds)and)frame 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 45
Thanks! 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 46
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 47
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 48
Examples 
Can$be$found$here: 
h"ps://github.com/Inferis/Prac7cal9AutoLayout 
Prac%cal'Autolayout'-'©'Tom'Adriaenssen,'2014 49

Practical auto layout