AutoLayout笔记

AutoLayout

AutoLayout基于描述性的constraints:

1
item1.attribute1 = multipler x item2.attribute2 + constant
1
2
3
4
5
6
7
+ (id)constraintWithItem:(id)item1
attribute:(NSLayoutAttribute)attribute1
relatedBy:(NSLayoutAttribute)relation
toItem:(id)item2
attribute:(NSLayoutAttribute)attribute2
multiplier:(CGFloat)multiplier
constant:(CGFloat)constant;

要将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起,为替代UIInterfaceOrientationUIUserInterfaceIdiom引入了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)保留合并进来的那个值。

参考