WWDC 2015

Mysteries of Auto Layout, Part 2

This session sums up most of the mysteries of auto layout developers come across.

The Layout cycle

Constraints change -> Deferred Layout Pass -> Application Run Loop

Constraints change

  • Activating or deactivating
  • Setting the constant or priority
  • Adding or removing views

Engine recomputes the layout

  • Engine variables receive new values
  • Views call superview.setNeedsLayout()

Deferred Layout Pass

  • Reposition misplaced views
  • Two passes through the view hierarchy
    • Update constraints
    • Reassign view frames
  • updateConstraints
    • Request via setNeedsUpdateConstraints()
  • Often not needed
    • Initial constraints in IB
    • Separate logic is harder to follow
  • Implement it when
    • Changing constraints in place is too slow
    • A view is making redundant changes
  • Traverse the view hierarchy, top-down
    • Call layoutSubViews()
      • only overriding it if constraints are insufficient
      • Some views have already been layied out
      • DO invoke super.layoutSubviews()
      • DO invalidate layout within your subtree
      • DO NOT call setNeedsUpdateConstraints() as it already done before
      • DO NOT invalidate layout outside your subtree as it is not under your control
      • DO NOT Modify constraints indiscriminately

Interacting with legacy layout (the layout before auto layout)

set translatesAutoresizingMaskIntoConstraints to false for programmatically created views in order to flag the engine to not create constraints for autoresizing masks

IB takes care it.

Layout Constraint Creation

iOS 9 new anchor property to make the code more readable view.topAnchor.constraintEqualToAnchor(view.topAnchor, costant:10) view.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, costant:10)

Constraining Negative Space

We often create dummy views for layouting or grouping some UI elements.

UILayoutGuide is new class in iOS 9 for representing a rectangle in layout engine

var layoutMarginsGuide: UILayoutGuide for internal padding of a view

Debugging Your Layout

  • Setting identifiers for constraints helps in debug
  • Set accessibility identifiers
  • Set identifiers on layout guides
  • (lldb) [view constraintsAffectingLayoutForAxis:1] for debugging only one axis ( 0 = horizontal , 1 = vertical)

Ambiguous Layouts

  • (lldb) [view _autolayoutTrace] for showing all constraints in debug logs
  • view.hasAmbiguousLayout() to see if the view has Ambiguous Layouts
  • (lldb) [view exerciseAmbiguityInLayout] for simulator running Ambiguous Layouts and (lldb) c to resume the process
  • Start the debug logs from the bottom

Related Session