AutoLayout
AutoLayout基于描述性的constraints:
1 | item1.attribute1 = multipler x item2.attribute2 + constant |
1 | + (id)constraintWithItem:(id)item1 |
要将constraint加到item1和item2的最近公共祖先 (Least Common Ancestor) 中:
1 | - (void)addConstraint:(NSLayoutConstraint *)constraint; |
AutoLayout先自底向上updateConstraints,再自顶向下layoutSubviews。layoutSubviews时调view的setCenter:
和setBounds:
constraint的priority默认1000(required constraint),当priority<1000时表示optional constraint,数值越高优先级越高。
Intrinsic Content Size & Compression Resistance & Content Hugging:
debug
- ambigulous: multiple layouts satisfy all constraints equally well
- unsatisfiability: no layout can satisfy all required constraints
查看autolayout情况:
1 | (lldb) po [view _autolayoutTrace] |
是否ambigulous:
1 | [view hasAmbiguousLayout] |
换成ambigulous的另一个layout:
1 | [view exerciseAmbiguityInLayout] |
显示紫色半透明的布局错误提示层:
1 | [window visualizeConstraints:@[]] |
可设置NSUserDefaults的NSConstraintBasedLayoutVisualizeMutallyExclusiveConstraint
为YES,则当布局出错时自动调用[window visualizeConstraints:]
什么constraints导致view的当前大小:
1 | [view constraintsAffectingLayoutForAxis:NSLayoutConstraintOrientationHorizontal/Vertical] |
转换自autoresizing mask的constraints:h=-&- v=&--
:h=
/v=
分别表示horizontal/vertical方向,-
表示fixed size,&
表示flexible size,3个符号依次表示margin, dimension, margin
Size Classes
iOS 8起,为替代UIInterfaceOrientation
和UIUserInterfaceIdiom
引入了Size Classes
参见:Traits Describe the Size Class and Scale of an Interface
There are two types of size classes in iOS 8: regular and compact. A regular size class denotes either a large amount of screen space, such as on an iPad, or a commonly adopted paradigm that provides the illusion of a large amount of screen space, such as scrolling on an iPhone.
With the amount of screen space available, the iPad has a regular size class in the vertical and horizontal directions in both portrait and landscape orientations.
The size classes for iPhones differ based on the kind of device and its orientation. In portrait, the screen has a compact size class horizontally and a regular size class vertically. This corresponds to the common usage paradigm of scrolling vertically for more information. When iPhones are in landscape, their size classes vary. Most iPhones have a compact size class both horizontally and vertically
default size classes
- iPad landscape&portait: V Regular | H Regular
- iPhone portait: V Regular | H Compact
- iPhone landscape: V Compact | H Compact
Traits
布局相关的属性,如 horizontalSizeClass / verticalSizeClass / userInterfaceIdiom / displayScale,都集中在对象的traitCollection中。
支持布局的对象,如 UIScreen / UIWindow / UIViewController / UIView / UIPresentationController,都实现了UITraitEnvironment协议,可以返回当前的traitCollection。UIViewController / UIView 也可以重载traitCollectionDidChange:
来监听traitCollection的改变。
traitCollection中未指定的trait就是Unspecified的。若traiCollection A中所有已指定的trait都与traitCollection B中的相等,则说A包含于B。两个traitCollection还能合并,X和Unspecified合并成X,值有冲突的(如Compact和Regular)保留合并进来的那个值。
参考
- Introduction to AutoLayout for iOS and OS X, WWDC2012#202
- Best Practices for Mastering Auto Layout, WWDC2012#228
- Auto Layout by Example, WWDC2012#232
- Visual Format Language
- Building Adaptive Apps with UIKit, WWDC2014#216
- 为iPhone6设计自适应布局:AutoLayout、SizeClasses
- Advanced Auto Layout Toolbox