Autolayout

80
[email protected] Layout Auto

description

Recorrido por todos los aspectos relevantes del uso de autolayout en iOS.

Transcript of Autolayout

Page 1: Autolayout

[email protected]

LayoutAuto

Page 2: Autolayout

LayoutAuto

Layout

Page 3: Autolayout

boundscenter } frame

transformautoresizingMask

Layout

frame.origin = center - (bounds.size / 2.0)center = frame.origin + (bounds.size / 2.0)

frame.size = bounds.size

Page 4: Autolayout

boundscenter } frame

transformautoresizingMask

Layout

frame.origin = center - (bounds.size / 2.0)center = frame.origin + (bounds.size / 2.0)

frame.size = bounds.size

Page 5: Autolayout

Layout

AutoLayout

AutoLayout

Page 6: Autolayout

LayoutAutoLayout

Page 7: Autolayout

LayoutAutoLayout

descriptiveconstraint-basedpixel-perfectmodular

view1.attribute1 RELATION multiplier * view2.attribute2 + constant

button.center.y = 1 * superview.center.y + 0

! [NSLayoutConstraint ! constraintWithItem: buttom! attribute: NSLayoutAttributeCenterY! relatedBy: NSLayoutRelationEqual! toItem: superview! attribute: NSLayoutAttributeCenterY! multiplier: 1.0! constant: 0.0]

Page 8: Autolayout

What do I need to know?

Page 9: Autolayout

What do I need to know?

UIView propertiesalignmentRectInsetsconstraints contentSizecompression huggingtranslatesAutoresizingMaskIntoConstraints

Page 10: Autolayout

What do I need to know?

UIView propertiesInterface Builder > VFL > API

Page 11: Autolayout

What do I need to know?

UIView propertiesInterface Builder > VFL > APIUIViewController lifecycle

Page 12: Autolayout

What do I need to know?

UIView propertiesInterface Builder > VFL > APIAnimation

Page 13: Autolayout

UIView Properties

Page 14: Autolayout

constraints

LayoutContent

Autosizing

NSLayoutConstraint NSContentSizeLayoutConstraint NSAutoresizingMaskLayoutConstraint

Page 15: Autolayout

constraintsview1.attribute1 RELATION multiplier * view2.attribute2 + constant

NSLayoutAttributeLeftNSLayoutAttributeRightNSLayoutAttributeTopNSLayoutAttributeBottomNSLayoutAttributeLeadingNSLayoutAttributeTrailingNSLayoutAttributeWidthNSLayoutAttributeHeightNSLayoutAttributeCenterXNSLayoutAttributeCenterYNSLayoutAttributeBaseline

NSLayoutAttributeNotAnAttribute

NSLayoutRelationEqualNSLayoutRelationGreaterThanOrEqualNSLayoutRelationLessThanOrEqual

Page 16: Autolayout

constraints

! [NSLayoutConstraint ! constraintWithItem: button! attribute: NSLayoutAttributeCenterX! relatedBy: NSLayoutRelationEqual! toItem: superview! attribute: NSLayoutAttributeCenterX! multiplier: 1.0! constant: 0.0]

Page 17: Autolayout

constraintsview1.attribute1 RELATION multiplier * view2.attribute2 + constant

! constraint = [NSLayoutConstraint ! constraintWithItem: view! attribute: NSLayoutAttributeWidth! relatedBy: NSLayoutRelationEqual! toItem: nil! attribute: NSLayoutAttributeNotAnAttribute! multiplier: 1.0! constant: 100.0]; [view addConstraint: constraint];

! constraint = [NSLayoutConstraint ! constraintWithItem: view! attribute: NSLayoutAttributeWidth! relatedBy: NSLayoutRelationEqual! toItem: nil! attribute: NSLayoutAttributeNotAnAttribute! multiplier: 1.0! constant: 80.0]; [view addConstraint: constraint];

size=100x80

CONSTRAINT_SIZE(view,100,80);

Page 18: Autolayout

constraintsview1.attribute1 RELATION multiplier * view2.attribute2 + constant

linear equationsCassowary Linear Arithmetic Constraint Solving AlgorithmPro tip: Use local flat hierarchies.

Page 19: Autolayout

constraintsview1.attribute1 RELATION multiplier * view2.attribute2 + constant

http://pilky.me/view/36

Page 20: Autolayout

constraintsview1.attribute1 RELATION multiplier * view2.attribute2 + constant

http://pilky.me/view/36

Page 21: Autolayout

constraints

Screw-ups

invisible view {

{crash

{undefined

Size not set

InvalidAmbiguousUnsatisfiable

Page 22: Autolayout

Unsatisfiable

Page 23: Autolayout

Invalid

Page 24: Autolayout

Ambiguous

view.hasAmbiguousLayoutview.exerciseAmbiguityInLayout

for (UIView *view in self.subviews) { if ([view hasAmbiguousLayout]){ NSLog(@"<%@:0x%0x>", view.description, (int)self); }}

Page 25: Autolayout

instrinsicContentSize

Suggested size for the view.

- (CGSize) intrinsicContentSize { return mySize;}

[self invalidateIntrinsicContentSize];

UIImage *img = UIImage imageNamed:@"Icon.png"];UIImageView *iv = [[UIImageView alloc] initWithImage:img];NSLog(@"%@", NSStringFromCGSize(iv.intrinsicContentSize));

Page 26: Autolayout

Alignment rectangle

UIView- (UIEdgeInsets)alignmentRectInsets

- (CGRect)frameForAlignmentRect:(CGRect)alignmentRect- (CGRect)alignmentRectForFrame:(CGRect)frame

Show rect lines:

Page 27: Autolayout

Hug & compressHugging resists stretching

Compression resists shrinking

UILayoutConstraintAxis axis = UILayoutConstraintAxisHorizontal;UILayoutPriority p = UILayoutPriorityDefaultHigh;[button setContentCompressionResistancePriority:p forAxis:axis];[button setContentHuggingPriority:p forAxis:axis];

Page 28: Autolayout

UIView propertiesInterface Builder > VFL > APIAnimation

Page 29: Autolayout

Interface Builder

Page 30: Autolayout

Interface Builder

Page 31: Autolayout

Interface Builder

Page 32: Autolayout

Interface Builder

Page 33: Autolayout

Interface Builder

Page 34: Autolayout

Interface Builder

IB > VFL > APIConstraints colorsIB can’t create ambiguous layoutsAdd a constraint before deleting anotherPreserve intrinsic sizeDon’t optimize until everything is in place

Page 35: Autolayout

UIView propertiesInterface Builder > VFL > APIAnimation

Page 36: Autolayout

Visual Format Language

Page 37: Autolayout

VFL[NSLayoutConstraint! constraintsWithVisualFormat:@"H:|-[buttonA]-|"! options:0! metrics:nil! views:@{ @"buttonA" : buttonA }];

Page 38: Autolayout

VFL

H V [view] | - @ ()

[NSLayoutConstraint! constraintsWithVisualFormat:@"H:|-[buttonA]-|"! options:0! metrics:nil! views:@{ @"buttonA" : buttonA }];

Page 39: Autolayout

VFL[NSLayoutConstraint! constraintsWithVisualFormat:@"H:|-[buttonA]-|"! options:0! metrics:nil! views:@{ @"buttonA" : buttonA }];

NSLayoutFormatAlignAllLeft NSLayoutFormatAlignAllRight NSLayoutFormatAlignAllTop NSLayoutFormatAlignAllBottom NSLayoutFormatAlignAllLeading NSLayoutFormatAlignAllTrailingNSLayoutFormatAlignAllCenterX NSLayoutFormatAlignAllCenterY NSLayoutFormatAlignAllBaseline

NSLayoutFormatAlignmentMask

NSLayoutFormatDirectionLeadingToTrailing NSLayoutFormatDirectionLeftToRight NSLayoutFormatDirectionRightToLeft

NSLayoutFormatDirectionMask

NSLayoutFormatOptions

Page 40: Autolayout

VFL[NSLayoutConstraint! constraintsWithVisualFormat:@"H:|-[buttonA]-distance-|"! options:0! metrics: @{ @"distance": @50 }! views:@{ @"buttonA" : buttonA }];

Page 41: Autolayout

VFL[NSLayoutConstraint! constraintsWithVisualFormat:@"H:|-[buttonA]-distance-|"! options:0! metrics: @{ @"distance": @50 }! views:@{ @"buttonA" : buttonA }];

Page 42: Autolayout

VFL[NSLayoutConstraint! constraintsWithVisualFormat:@"H:|-[buttonA]-distance-|"! options:0! metrics: @{ @"distance": @50 }! views:NSDictionaryOfVariableBindings(buttonA)];

Page 43: Autolayout

VFL

H V [view] | - @ ()

Page 44: Autolayout
Page 45: Autolayout
Page 46: Autolayout
Page 47: Autolayout
Page 48: Autolayout
Page 49: Autolayout

H:[view1][view2]

Page 50: Autolayout

H:[view1]-[view2]

Page 51: Autolayout

H:[view1]-30-[view2]H:[view1]-(==30)-[view2]

Page 52: Autolayout

H:|[view1]-[view2]|

Page 53: Autolayout

H:|-[view1]-(>=0)-[view2]-|

Page 54: Autolayout

H:|-[view1(>=125,<=250)]-(>=0)-[view2]-|

Page 55: Autolayout

H:[view1(>=view2)][view2]

Page 56: Autolayout

H:[button(100@20)]

H:|[view1]-(>=50@30)-[view2]|

H:|-[view1(==view2)]-[view2]-|

H:[view1(view2)]

...

Page 57: Autolayout

100x100 Square

- (void)viewDidLoad{ [super viewDidLoad];

self.blueView.translatesAutoresizingMaskIntoConstraints = NO;

[self.blueView setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal]; [self.blueView setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical];

[self.blueView removeConstraints:self.blueView.constraints]; [self.blueView.superview removeConstraints:self.blueView.superview.constraints];

NSArray *constraints = @[ @"H:[blueView(100)]", @"V:[blueView(100)]"]; NSDictionary *views = @{@"blueView":self.blueView}; for (NSString *format in constraints) { [self.view addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: format options: 0 metrics: nil views: views]]; }}

Page 58: Autolayout

UIView propertiesInterface Builder > VFL > APIAnimation

Page 59: Autolayout

UIView API

Page 60: Autolayout

UIView API

Opting in to Constraint-Based Layout

+ requiresConstraintBasedLayout – translatesAutoresizingMaskIntoConstraints – setTranslatesAutoresizingMaskIntoConstraints:

Managing Constraints

– constraints – addConstraint: – addConstraints: – removeConstraint: – removeConstraints:

Measuring in Constraint-Based Layout

– systemLayoutSizeFittingSize – intrinsicContentSize – invalidateIntrinsicContentSize – contentCompressionResistancePriorityForAxis: – setContentCompressionResistancePriority:forAxis: – contentHuggingPriorityForAxis: – setContentHuggingPriority:forAxis:

Page 61: Autolayout

UIView API

Aligning Views with Constraint-Based Layout

– alignmentRectForFrame: – frameForAlignmentRect: – alignmentRectInsets – viewForBaselineLayout

Triggering Constraint-Based Layout

– needsUpdateConstraints – setNeedsUpdateConstraints – updateConstraints – updateConstraintsIfNeeded

Debugging Constraint-Based Layout

– constraintsAffectingLayoutForAxis: – hasAmbiguousLayout – exerciseAmbiguityInLayout

Page 62: Autolayout

CALayer API

CALayer

– layoutIfNeeded

Page 63: Autolayout

UIViewController

viewDidLoad - autolayout-viewDidLayoutSubviewsviewDidAppear

[self.view layoutIfNeeded]

Page 64: Autolayout

UIView propertiesInterface Builder > VFL > APIAnimation

Page 65: Autolayout

Animation

Page 66: Autolayout

Animation#238: Animate the constant

Page 67: Autolayout

constant

self.someConstraint.constant = 10.0;[UIView animateWithDuration:0.25 animations:^{ [self.view layoutIfNeeded];}];

Page 68: Autolayout

Animation#238: Animate the constant.#238: Call layoutIfNeeded in a block.

Page 69: Autolayout

layoutIfNeeded

- (BOOL)continueTrackingWithTouch:(UITouch *)touchwithEvent:(UIEvent *)event{! CGPoint touchPoint = [touch locationInView:self];! [UIView animateWithDuration:0.1f animations:^(){! ! NSLayoutConstraint *constraint =! ! [trackView constraintNamed:THUMB_POSITION_TAG];! ! constraint.constant = touchPoint.x;! ! [trackView layoutIfNeeded];! }];! return YES;}

Page 70: Autolayout

Animation#238: Animate the constant.#238: Call layoutIfNeeded in a block.Animate layers instead of views.

Page 71: Autolayout

Layer animation

// jumpy[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionAutoreverseanimations:^{ v.transform = CGAffineTransformMakeScale(1.1, 1.1);} completion:^(BOOL finished) { v.transform = CGAffineTransformIdentity;}];

// smoothCABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"transform"];ba.autoreverses = YES;ba.duration = 0.3;ba.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1, 1.1, 1)];[v.layer addAnimation:ba forKey:nil];

Page 72: Autolayout

Animation#238: Animate the constant.#238: Call layoutIfNeeded in a block.Animate layers instead of views.Drop constraints, use autosizing masks.

Page 73: Autolayout

Animation#238: Animate the constant#238: Call layoutIfNeeded in a blockAnimate layers instead of views.Drop constraints, use autosizing masks.Use a container view.

Page 74: Autolayout

Animation#238: Animate the constant.#238: Call layoutIfNeeded in a block.Animate layers instead of views.Drop constraints, use autosizing masks.Use a container view.Use constraints that don’t interfere.

Page 75: Autolayout

Animation#238: Animate the constant.#238: Call layoutIfNeeded in a block.Animate layers instead of views.Drop constraints, use autosizing masks.Use a container view.Use constraints that don’t interfere.Set frame in viewDidLayoutSubviews.

Page 76: Autolayout

Animating Rotations

Page 77: Autolayout

Fading in/out during rotation

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toduration:(NSTimeInterval)duration{! // fade away old layout! [UIView animateWithDuration:duration animations:^{! for (UIView *view in @[settingsView, creditsView])! view.alpha = 0.0f;! }];} - (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)from{! // update the layout for the new orientation! [self updateViewConstraints];! [self.view layoutIfNeeded]; ! // fade in the new layout! [UIView animateWithDuration:0.3f animations:^{! for (UIView *view in @[settingsView, creditsView])! view.alpha = 1.0f;! }];}

Page 78: Autolayout

Update and animate changes

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toduration:(NSTimeInterval)duration{! [UIView animateWithDuration:duration animations:^{! ! [self updateViewConstraints];! ! [self.view layoutIfNeeded];! }];}

Page 79: Autolayout

Calling updates

UIDeviceOrientation newOrientation; - (void) updateViewConstraints{! [super updateViewConstraints];! [self.view removeConstraints:self.view.constraints];! if (newOrientation==UIDeviceOrientationPortrait){! ! // ...! }} - (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientationduration:(NSTimeInterval)duration{! newOrientation = toInterfaceOrientation;! [self updateViewConstraints];}

Page 80: Autolayout

References#202 WWDC 2012: Introduction to Auto Layout for iOS and OS X#228 WWDC 2012: Best Practices for Mastering Auto Layout#232 WWDC 2012: Auto Layout by Example#406 WWDC ’13 Taking Control of Auto Layout in Xcode 5

Cocoa Auto Layout Guide

iOS Auto Layout Demystified

$16