Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Session 228 - Best Practices for Mastering Auto Layout

wwdcman
June 25, 2012
1.5k

Session 228 - Best Practices for Mastering Auto Layout

wwdcman

June 25, 2012
Tweet

Transcript

  1. These are confidential sessions—please refrain from streaming, blogging, or taking

    pictures for OS X and iOS Session 228 Peter Ammon AppKit Engineer Best Practices for Mastering Auto Layout
  2. •One new class—NSLayoutConstraint •Constraints express geometric properties of views •Constraints

    also express geometric relationships between views NSLayoutConstraint foo foo.width = 120
  3. •One new class—NSLayoutConstraint •Constraints express geometric properties of views •Constraints

    also express geometric relationships between views NSLayoutConstraint foo foo.width = 120 foo foo.width = bar.width bar
  4. •One new class—NSLayoutConstraint •Constraints express geometric properties of views •Constraints

    also express geometric relationships between views NSLayoutConstraint foo foo.width = 120 foo foo.width = bar.width bar •Relationships have a coefficient and a constant
  5. •One new class—NSLayoutConstraint •Constraints express geometric properties of views •Constraints

    also express geometric relationships between views NSLayoutConstraint foo foo.width = 120 foo foo.width = bar.width bar •Relationships have a coefficient and a constant foo.width = bar.width * 2 - 20
  6. NSLayoutConstraint •Constraints can be equalities or inequalities foo foo.width >=

    120 •Constraints have priorities foo foo.width = 120 with priority 500 foo.width = 75 with priority 1000
  7. NSLayoutConstraint •Constraints can be created three ways ▪ Interface Builder

    ▪ Visual format language ▪ Base API •Prefer this order
  8. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint-based layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  9. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint-based layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  10. Thinking in Constraints •Auto Layout can be used like springs

    and struts •But you get the most benefits from a shift in thinking •Let your layouts becomes declarative
  11. Thinking in Constraints Q W E R T Y Springs

    and Struts padding containerWidth
  12. Thinking in Constraints Q W E R T Y Springs

    and Struts padding keyWidth = containerWidth / keyCount - padding * (keyCount + 1) / keyCount containerWidth
  13. Thinking in Constraints Q W E R T Y Springs

    and Struts padding keyOffset = padding + keyIndex * (keyWidth + padding) keyWidth = containerWidth / keyCount - padding * (keyCount + 1) / keyCount containerWidth
  14. Thinking in Constraints Auto Layout Q W E R T

    Y Q.width = container.width / keyCount - padding * (keyCount + 1) / keyCount Relationships
  15. Thinking in Constraints Auto Layout Q W E R T

    Y Q.width = container.width / keyCount - padding * (keyCount + 1) / keyCount Relationships
  16. Thinking in Constraints Auto Layout Q W E R T

    Y Q.width = container.width / keyCount - padding * (keyCount + 1) / keyCount Q.minX = container.minX + padding W.minX = Q.maxX + padding E.minX = W.maxX + padding... Relationships
  17. Thinking in Constraints Auto Layout Q W E R T

    Y Q.width = container.width / keyCount - padding * (keyCount + 1) / keyCount Q.minX = container.minX + padding W.minX = Q.maxX + padding E.minX = W.maxX + padding... Relationships
  18. Thinking in Constraints Q W E R T Y Auto

    Layout Q.minX = container.minX + padding W.minX = Q.maxX + padding E.minX = W.maxX + padding...
  19. Thinking in Constraints Q W E R T Y Auto

    Layout Q.minX = container.minX + padding W.minX = Q.maxX + padding E.minX = W.maxX + padding... =
  20. Thinking in Constraints Q W E R T Y Auto

    Layout Q.minX = container.minX + padding W.minX = Q.maxX + padding E.minX = W.maxX + padding... = Q.width = W.width W.width = E.width ...
  21. Thinking in Constraints Q W E R T Y Auto

    Layout Q.minX = container.minX + padding W.minX = Q.maxX + padding E.minX = W.maxX + padding... = Q.width = W.width W.width = E.width ...
  22. Thinking in Constraints Q W E R T Y Auto

    Layout Q.minX = container.minX + padding W.minX = Q.maxX + padding E.minX = W.maxX + padding... = Q.width = W.width W.width = E.width ... container.maxX = Y.maxX + padding
  23. •Layout becomes distributed •Decompose sophisticated layouts into components •Each component

    contributes the constraints it cares about •Layout becomes “owned” Thinking in Constraints
  24. •Layout becomes distributed •Decompose sophisticated layouts into components •Each component

    contributes the constraints it cares about •Layout becomes “owned” Thinking in Constraints Q
  25. •Layout becomes distributed •Decompose sophisticated layouts into components •Each component

    contributes the constraints it cares about •Layout becomes “owned” Thinking in Constraints Q I’m square!
  26. •Layout becomes distributed •Decompose sophisticated layouts into components •Each component

    contributes the constraints it cares about •Layout becomes “owned” Thinking in Constraints Q I’m square!
  27. •Layout becomes distributed •Decompose sophisticated layouts into components •Each component

    contributes the constraints it cares about •Layout becomes “owned” Thinking in Constraints Q I’m square! Be centered vertically in me! Be the same height as me!
  28. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint-based layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  29. 1. Plan your attack •A partial conversion lets you use

    Auto Layout just where you need it ▪ Some compatibility issues to be aware of •A full conversion will pay major dividends Migrating from Springs and Struts
  30. 2. Turn on Auto Layout in your nibs •Create the

    constraints you want in IB •IB will create constraints that reflect your existing layout •Add to or modify them Migrating from Springs and Struts
  31. 3. Turn off autoresizing mask translation for every view you

    create programmatically [view setTranslatesAutoresizingMaskIntoConstraints:NO] •If you forget, you’ll get unsatisfiable constraint warnings quickly Migrating from Springs and Struts
  32. 4. Look for places where you perform layout - (void)layoutSubviews

    {… Migrating from Springs and Struts [view setFrame:rect] [view setFrameSize:size] [view setFrameOrigin:point]
  33. 4. Look for places where you perform layout - (void)layoutSubviews

    {… Migrating from Springs and Struts [view setFrame:rect] [view setFrameSize:size] [view setFrameOrigin:point] They all have to go!
  34. 4. Look for places where you perform layout - (void)layoutSubviews

    {… Migrating from Springs and Struts [view setFrame:rect] [view setFrameSize:size] [view setFrameOrigin:point] They all have to go! (But what do I replace them with?)
  35. Migrating from Springs and Struts •Stop and think ▪ Don’t

    try to merely replicate what the existing code is doing ▪ Think about the underlying layout
  36. Migrating from Springs and Struts •Stop and think ▪ Don’t

    try to merely replicate what the existing code is doing ▪ Think about the underlying layout •Try replacing it with nothing! ▪ Are you working around a limitation of springs and struts? ▪ Does the code implement a relationship?
  37. Migrating from Springs and Struts •Stop and think ▪ Don’t

    try to merely replicate what the existing code is doing ▪ Think about the underlying layout •Try replacing it with nothing! ▪ Are you working around a limitation of springs and struts? ▪ Does the code implement a relationship? •Otherwise, add some constraints
  38. Migrating from Springs and Struts •Think about which component should

    own each constraint •Consider centralizing it in updateConstraints
  39. 5. Test it •Verify the layout is correct •Fix issues

    you may have Migrating from Springs and Struts
  40. 5. Test it •Verify the layout is correct •Fix issues

    you may have Migrating from Springs and Struts •Wait, what?
  41. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint-based layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  42. •Constraints that provide insufficient information ▪ Ambiguity •Constraints that provide

    conflicting information ▪ Unsatisfiability •Constraints that are satisfied in unexpected ways What Can Go Wrong?
  43. •Interface Builder prevents unsatisfiable or ambiguous constraints •Rely on Interface

    Builder as much as possible •You can reference constraints with outlets What Can Go Wrong?
  44. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint-based layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  45. Ambiguity •Ambiguity means multiple layouts satisfy all constraints equally well

    •A common symptom is that your views will cycle between those layouts
  46. Ambiguity •Ambiguity means multiple layouts satisfy all constraints equally well

    •A common symptom is that your views will cycle between those layouts •Views “jump” or disappear entirely (jump to zero size)
  47. •Usually it means you need more constraints •Each view needs

    four properties (two in each dimension) ▪ MinX, Width, MinY, Height ▪ MinX, MaxX, CenterY, MaxY ▪ CenterX, Width, Baseline, Height ▪ etc. Ambiguity
  48. •Usually it means you need more constraints •Each view needs

    four properties (two in each dimension) ▪ MinX, Width, MinY, Height ▪ MinX, MaxX, CenterY, MaxY ▪ CenterX, Width, Baseline, Height ▪ etc. •Inequalities by themselves are usually not enough ▪ view.width ≥ 20 – is it 20? 200? 2 billion? ▪ Inequalities don’t care how much larger or smaller you are ▪ But equalities care Ambiguity
  49. •Rarely, ambiguity means you need to adjust priorities Ambiguity •It

    can’t satisfy both •They have equal priorities •Ambiguity! [view(24@500) [view(>=30@500)]
  50. •Rarely, ambiguity means you need to adjust priorities Ambiguity •It

    still can’t satisfy both [view(24@500) [view(>=30@525)]
  51. •Rarely, ambiguity means you need to adjust priorities Ambiguity •It

    still can’t satisfy both •The inequality has a higher priority, so it will be satisfied first [view(24@500) [view(>=30@525)]
  52. •Rarely, ambiguity means you need to adjust priorities Ambiguity •It

    still can’t satisfy both •The inequality has a higher priority, so it will be satisfied first •The equality will be satisfied as closely as possible [view(24@500) [view(>=30@525)]
  53. •Rarely, ambiguity means you need to adjust priorities Ambiguity •It

    still can’t satisfy both •The inequality has a higher priority, so it will be satisfied first •The equality will be satisfied as closely as possible •No ambiguity! [view(24@500) [view(>=30@525)]
  54. •Rarely, ambiguity means you need to adjust priorities Ambiguity •It

    still can’t satisfy both •The inequality has a higher priority, so it will be satisfied first •The equality will be satisfied as closely as possible •No ambiguity! •view.width = 30 [view(24@500) [view(>=30@525)]
  55. •Is my layout ambiguous? [view hasAmbiguousLayout] •What is ambiguous about

    it? [view exerciseAmbiguityInLayout] [window visualizeConstraints: @[] ] Ambiguity
  56. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint-based layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  57. •Unsatisfiability means no layout can satisfy all required constraints •Only

    required constraints can contribute to unsatisfiability ▪ Constraints are required by default! Unsatisfiability
  58. •Unsatisfiability means no layout can satisfy all required constraints •Only

    required constraints can contribute to unsatisfiability ▪ Constraints are required by default! •Sizes are implicitly required to be at least zero Unsatisfiability
  59. •Unsatisfiability is immediately reported •Ambiguity can be temporarily tolerated •Remove

    constraints as soon as they might become invalid •Create valid constraints again in updateConstraints Unsatisfiability
  60. Help, I Don’t See Anything! •Where are your views? ▪

    Check their -frame •What constraints are making them that size? ▪ Output [view constraintsAffectingLayoutForOrientation/Axis: NSLayoutConstraintOrientationHorizontal/Vertical]
  61. Help, I Don’t See Anything! •Where are your views? ▪

    Check their -frame •What constraints are making them that size? ▪ Output [view constraintsAffectingLayoutForOrientation/Axis: NSLayoutConstraintOrientationHorizontal/Vertical] 0 or 1
  62. Help, I Don’t See Anything! •Where are your views? ▪

    Check their -frame •What constraints are making them that size? ▪ Output [view constraintsAffectingLayoutForOrientation/Axis: NSLayoutConstraintOrientationHorizontal/Vertical] •Is the layout ambiguous? ▪ Call [view hasAmbiguousLayout] ▪ Call [view exerciseAmbiguityInLayout] 0 or 1
  63. Help, I Don’t See Anything! •Some layouts are only satisfiable

    at 0 size! foo.width = bar.width * 2 bar.width = foo.width * 3
  64. Help, I Don’t See Anything! •Some layouts are only satisfiable

    at 0 size! foo.width = bar.width * 2 bar.width = foo.width * 3 foo.width = bar.width = 0
  65. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint-based layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  66. Anatomy of an Unsatisfiability Log Unable to simultaneously satisfy constraints:

    ( "<NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 )>", "<NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )> Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens. And/or, break on objc_exception_throw to catch this in the debugger.
  67. Unable to simultaneously satisfy constraints: ( "<NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile:

    0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 )>", "<NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )> Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens. And/or, break on objc_exception_throw to catch this in the debugger. Anatomy of an Unsatisfiability Log
  68. Unable to simultaneously satisfy constraints: ( "<NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile:

    0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 )>", "<NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )> Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens. And/or, break on objc_exception_throw to catch this in the debugger. Anatomy of an Unsatisfiability Log
  69. Anatomy of an Unsatisfiability Log Unable to simultaneously satisfy constraints:

    ( "<NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 )>", "<NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )> Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens. And/or, break on objc_exception_throw to catch this in the debugger.
  70. Anatomy of an Unsatisfiability Log Unable to simultaneously satisfy constraints:

    ( "<NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 )>", "<NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )> Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens. And/or, break on objc_exception_throw to catch this in the debugger.
  71. Anatomy of an Unsatisfiability Log Unable to simultaneously satisfy constraints:

    ( "<NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 )>", "<NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )> Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens. And/or, break on objc_exception_throw to catch this in the debugger.
  72. Anatomy of an Unsatisfiability Log Unable to simultaneously satisfy constraints:

    ( "<NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 )>", "<NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )> Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens. And/or, break on objc_exception_throw to catch this in the debugger.
  73. Anatomy of an Unsatisfiability Log Unable to simultaneously satisfy constraints:

    ( "<NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 )>", "<NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )> Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens. And/or, break on objc_exception_throw to catch this in the debugger.
  74. Anatomy of an Unsatisfiability Log Unable to simultaneously satisfy constraints:

    ( "<NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 )>", "<NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x10441ce70 LetterView-'H'.centerX == LetterPile: 0x102b25230.centerX + 170 (Names: LetterView-'H':0x10423c390 )> Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens. And/or, break on objc_exception_throw to catch this in the debugger.
  75. NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile:0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 ) Anatomy

    of an Unsatisfiability Log Map from identifier to view •View identifiers make logs easier to read
  76. NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile:0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 ) Anatomy

    of an Unsatisfiability Log Map from identifier to view •View identifiers make logs easier to read
  77. NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile:0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 ) Anatomy

    of an Unsatisfiability Log Map from identifier to view •View identifiers make logs easier to read
  78. NSLayoutConstraint:0x10441ced0 LetterView-'H'.centerX == LetterPile:0x102b25230.centerX - 11 (Names: LetterView-'H':0x10423c390 ) Anatomy

    of an Unsatisfiability Log View’s identifier Attribute Relation Other View Constant “The letter view’s center should be 11 points to the left of the pile’s center”
  79. Anatomy of an Unsatisfiability Log •Logs use the visual format

    syntax when possible H:[NSView:0x102b5b3a0(250)]
  80. Anatomy of an Unsatisfiability Log •Logs use the visual format

    syntax when possible H:[NSView:0x102b5b3a0(250)] “The view’s width is 250”
  81. Anatomy of an Unsatisfiability Log •Logs use the visual format

    syntax when possible H:[NSView:0x102b5b3a0(250)] H:[NSView:0x10480cd00]-(>=50)-[NSView:0x10481e9a0]> “The view’s width is 250”
  82. Anatomy of an Unsatisfiability Log •Logs use the visual format

    syntax when possible H:[NSView:0x102b5b3a0(250)] H:[NSView:0x10480cd00]-(>=50)-[NSView:0x10481e9a0]> “The view’s width is 250” “This view is at least 50 points to the right of that view”
  83. Anatomy of an Unsatisfiability Log <NSAutoresizingMaskLayoutConstraint:0x10590a360 h=-&- v=&-- V:[NSView:0x102e2af20(50)]> •

    translatesAutoresizingMaskIntoConstraints is on for this view •That produces more than one constraint Autoresizing Mask
  84. Anatomy of an Unsatisfiability Log <NSAutoresizingMaskLayoutConstraint:0x10590a360 h=-&- v=&-- V:[NSView:0x102e2af20(50)]> •

    translatesAutoresizingMaskIntoConstraints is on for this view •That produces more than one constraint Autoresizing Mask
  85. Anatomy of an Unsatisfiability Log <NSAutoresizingMaskLayoutConstraint:0x10590a360 h=-&- v=&-- V:[NSView:0x102e2af20(50)]> •

    translatesAutoresizingMaskIntoConstraints is on for this view •That produces more than one constraint Autoresizing Mask “This view’s height is 50.”
  86. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint-based layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  87. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint based-layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  88. Animation •How do you animate layout changes? •Apply the new

    layout and let CoreAnimation handle animation ▪ Very fast ▪ May transiently appear to violate constraints
  89. Animation •How do you animate layout changes? •Apply the new

    layout and let CoreAnimation handle animation ▪ Very fast ▪ May transiently appear to violate constraints •Animate constraints directly ▪ Pretty fast ▪ Produces a correct layout at every frame
  90. Animation with CoreAnimation •Adjust your constraints •Within an animation block,

    call [view layoutIfNeeded] on iOS [view layoutSubtreeIfNeeded] on OS X
  91. Animation with CoreAnimation •NSView [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) { [context setDuration:0.5];

    [context setAllowsImplicitAnimation:YES]; [view layoutSubtreeIfNeeded]; } completionHandler:nil] •UIView [UIView animateWithDuration:0.5 animations:^{ [view layoutIfNeeded]; }]
  92. Animation with NSLayoutConstraint @interface NSLayoutConstraint @property (readonly) NSLayoutAttribute firstAttribute; @property

    (readonly) CGFloat multiplier; @property (readwrite) CGFloat constant; @end •The constant may be modified after creation
  93. Animation with NSLayoutConstraint @interface NSLayoutConstraint @property (readonly) NSLayoutAttribute firstAttribute; @property

    (readonly) CGFloat multiplier; @property (readwrite) CGFloat constant; @end •The constant may be modified after creation •Permits efficient relayouts
  94. Animation with NSLayoutConstraint @interface NSLayoutConstraint @property (readonly) NSLayoutAttribute firstAttribute; @property

    (readonly) CGFloat multiplier; @property (readwrite) CGFloat constant; @end •The constant may be modified after creation •Permits efficient relayouts •Use an NSTimer
  95. Animation with NSLayoutConstraint @interface NSLayoutConstraint @property (readonly) NSLayoutAttribute firstAttribute; @property

    (readonly) CGFloat multiplier; @property (readwrite) CGFloat constant; @end •The constant may be modified after creation •Permits efficient relayouts •Use an NSTimer constraint.constant += 10
  96. Animation with NSLayoutConstraint @interface NSLayoutConstraint @property (readonly) NSLayoutAttribute firstAttribute; @property

    (readonly) CGFloat multiplier; @property (readwrite) CGFloat constant; @end •The constant may be modified after creation •Permits efficient relayouts •Use an NSTimer •Use the animator proxy constraint.constant += 10
  97. Animation with NSLayoutConstraint @interface NSLayoutConstraint @property (readonly) NSLayoutAttribute firstAttribute; @property

    (readonly) CGFloat multiplier; @property (readwrite) CGFloat constant; @end •The constant may be modified after creation •Permits efficient relayouts •Use an NSTimer •Use the animator proxy constraint.constant += 10 constraint.animator.constant = 10
  98. Animation with NSLayoutConstraint @interface NSLayoutConstraint @property (readonly) NSLayoutAttribute firstAttribute; @property

    (readonly) CGFloat multiplier; @property (readwrite) CGFloat constant; @end •The constant may be modified after creation •Permits efficient relayouts •Use an NSTimer •Use the animator proxy constraint.constant += 10 constraint.animator.constant = 10 OS X only
  99. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint-based layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  100. Alignment Rects •Constraints operate on content, not frames •The content

    area is called the alignment rect Push Me Push Me Push Me Push Me
  101. Alignment Rects •Constraints operate on content, not frames •The content

    area is called the alignment rect Push Me Push Me Push Me ? ? ? Push Me
  102. Alignment Rects •Constraints operate on content, not frames •The content

    area is called the alignment rect Push Me Frame Alignment Rect
  103. Alignment Rects •You can convert between alignment rects and frames

    @implementation (NS,UI)View - (CGRect)alignmentRectForFrame:(CGRect)frame - (CGRect)frameForAlignmentRect:(CGRect)alignmentRect
  104. Intrinsic Content Size •Many views are equally happy at any

    size •Some views have a preferred size sizeToFit sizeThatFits: •In Auto Layout, this is the intrinsicContentSize
  105. Intrinsic Content Size •Many views are equally happy at any

    size •Some views have a preferred size sizeToFit sizeThatFits: •In Auto Layout, this is the intrinsicContentSize Push Me
  106. Intrinsic Content Size •Many views are equally happy at any

    size •Some views have a preferred size sizeToFit sizeThatFits: •In Auto Layout, this is the intrinsicContentSize Push Me
  107. Intrinsic Content Size •Many views are equally happy at any

    size •Some views have a preferred size sizeToFit sizeThatFits: •In Auto Layout, this is the intrinsicContentSize Push Me ?
  108. Intrinsic Content Size •An intrinsic content size generates two constraints

    per dimension Push Me 120 25 H:[button(>=120] H:[button(<=120] V:[button(>=25)] V:[button(<=25)]
  109. Intrinsic Content Size •An intrinsic content size generates two constraints

    per dimension Push Me 120 25 H:[button(>=120] H:[button(<=120] V:[button(>=25)] V:[button(<=25)] Compression Resistance
  110. Intrinsic Content Size •An intrinsic content size generates two constraints

    per dimension Push Me 120 25 H:[button(>=120] H:[button(<=120] V:[button(>=25)] V:[button(<=25)] Compression Resistance Content Hugging
  111. Intrinsic Content Size •An intrinsic content size generates two constraints

    per dimension Push Me 120 25 H:[button(>=120] H:[button(<=120] V:[button(>=25)] V:[button(<=25)] •This is sufficient to unambiguously size the view! Compression Resistance Content Hugging
  112. Intrinsic Content Size •Why two constraints? •Because they can have

    different priorities! This is a label This is a label
  113. Intrinsic Content Size •Why two constraints? •Because they can have

    different priorities! This is a label This is… This is a label
  114. Intrinsic Content Size •Why two constraints? •Because they can have

    different priorities! This is a label This is… This is a label •Low content hugging priority, high compression resistance priority
  115. Intrinsic Content Size •Why two constraints? •Because they can have

    different priorities! •High content hugging priority, high compression resistance priority Push Me Push Me Pus…
  116. Intrinsic Content Size •Intrinsic content size is not settable •The

    constraint priorities are settable @implementation NSView - (void)setContentHuggingPriority:(NSLayoutPriority)priority forOrientation:(NSLayoutConstraintOrientation)orientation; - (void)setContentCompressionResistancePriority:(NSLayoutPriority)priority forOrientation:(NSLayoutConstraintOrientation)orientation; @end
  117. Intrinsic Content Size •Intrinsic content size is not settable •The

    constraint priorities are settable @implementation UIView - (void)setContentHuggingPriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis; - (void)setContentCompressionResistancePriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis; @end
  118. Intrinsic Content Size •The view calls [self invalidateIntrinsicContentSize] whenever its

    content changes •Auto Layout reestablishes the sizing constraints •If you implement a custom control, call this whenever your intrinsicContentSize might change Short Label Longer L…
  119. Intrinsic Content Size •The view calls [self invalidateIntrinsicContentSize] whenever its

    content changes •Auto Layout reestablishes the sizing constraints •If you implement a custom control, call this whenever your intrinsicContentSize might change Short Label Longer L… Longer Longer Label
  120. Intrinsic Content Size intrinsicContentSize as a better sizeToFit •sizeToFit must

    preserve binary compatibility •It may be wrong for the current artwork •intrinsicContentSize can change •Use intrinsicContentSize as a better sizeToFit
  121. Intrinsic Content Size intrinsicContentSize as a better sizeToFit •sizeToFit must

    preserve binary compatibility •It may be wrong for the current artwork •intrinsicContentSize can change •Use intrinsicContentSize as a better sizeToFit NSRect alignmentRect = (NSRect){NSZeroPoint, [control intrinsicContentSize]}; [control setFrameSize: [control frameForAlignmentRect:alignmentRect].size];
  122. Override intrinsicContentSize Writing a Custom Control •Do ▪ Measure text

    or images ▪ Hard-code values •Do not ▪ Inspect your position, size, or constraints ▪ Call super and “tweak” its value ▪ Use it as a substitute for explicit constraints
  123. Indicate your alignment rect Writing a Custom Control •Do ▪

    Consider using the default implementation ▪ Override - (NS/UIEdgeInsets)alignmentRectInsets;
  124. Indicate your alignment rect Writing a Custom Control •Do ▪

    Consider using the default implementation ▪ Override - (NS/UIEdgeInsets)alignmentRectInsets; •Do not ▪ Inspect your position, size, or constraints ▪ Call super and “tweak” its value ▪ Use it as a substitute for explicit constraints
  125. Overriding layout / layoutSubviews -layout sets the receiver’s frame to

    the values determined by the constraints NSView
  126. Overriding layout / layoutSubviews -layout sets the receiver’s frame to

    the values determined by the constraints NSView -layoutSubviews sets the receiver’s center and bounds to the values determined by the constraints UIView
  127. Overriding layout / layoutSubviews •Afterwards, the constraints and frames agree

    •Override it to do custom layout as long as you maintain that invariant -layout sets the receiver’s frame to the values determined by the constraints NSView -layoutSubviews sets the receiver’s center and bounds to the values determined by the constraints UIView
  128. Overriding layout / layoutSubviews Achieving a layout-dependent view hierarchy •Override

    -layout / -layoutSubviews •Call super •Inspect the resulting view positions and sizes •Adjust subviews and constraints •Call super again •Repeat!
  129. Auto Layout •Thinking in constraints ▪ Transitioning to constraints •Debugging

    constraint-based layouts ▪ Ambiguity ▪ Unsatisfiability ▪ Reading log messages •Unleashing the power of constraints ▪ Animation ▪ Writing a custom control ▪ Internationalization
  130. Internationalization •Auto Layout makes internationalization easier ▪ Controls size according

    to their content ▪ The same constraints still work across different localizations
  131. Internationalization •Auto Layout makes internationalization easier ▪ Controls size according

    to their content ▪ The same constraints still work across different localizations Save Cancel
  132. Internationalization •Auto Layout makes internationalization easier ▪ Controls size according

    to their content ▪ The same constraints still work across different localizations Sichern Abbrechen
  133. Internationalization •One nib can now service multiple localizations •Control content

    is translated with a strings file at runtime •You can fall back to separate nibs when necessary Sichern Abbrechen
  134. Internationalization •Right-to-left support is built in •The leading and trailing

    edges flip under right-to-left localizations Sichern Abbrechen
  135. !"# ء%&'إ Internationalization •Right-to-left support is built in •The leading

    and trailing edges flip under right-to-left localizations Sichern Abbrechen
  136. Summary •Auto Layout allows for powerful layout with less (or

    no) code •Think declaratively •Be wary of ambiguity and unsatisfiability •The log messages are there to help •Judicious overriding lets your custom views integrate with Auto Layout •Localize with a single nib and multiple strings files
  137. More Information Paul Marcos Frameworks Evangelist [email protected] Documentation Cocoa Auto

    Layout Guide http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/ Apple Developer Forums http://devforums.apple.com