AutoLayout大部分情况下是在IB中设计的,如果需要在代码中设计,可以使用NSLayoutConstraint、Layout Anchors、Visual Format Language三种方式来创造Constraints。
NSLayoutConstraint Class
直接通过NSLayoutConstraint Class的函数可以在相应的View上添加Constraints:
1 | UIView *testView = [[UIView alloc] init]; |
这里,要注意的是,在创建Constraints之前,需要将对应的View添加到View结构树中去:
1 | [self.view addSubview:testView]; |
否则,会报错:
1 | **Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with items <UIView: 0x7fe56a421c20; frame = (0 0; 0 0); layer = <CALayer: 0x7fe56a41c6e0>> and <UIView: 0x7fe56a426e80; frame = (0 0; 667 375); autoresize = W+H; layer = <CALayer: 0x7fe56a424fa0>> because they have no common ancestor. Does the constraint reference items in different view hierarchies? That's illegal.' |
另外,需要设置translatesAutoresizingMaskIntoConstraints属性为NO:
1 | testView.translatesAutoresizingMaskIntoConstraints = NO; |
否则,会报错:
1 | Unable to simultaneously satisfy constraints. |
当出现约束错误时,NSLayoutConstraint Class不会在编译时报错,只会在运行时报错。
Layout Anchors
由于NSLayoutConstraint Class比较复杂,易读性较差,所以,iOS 9以上系统又提供了更便捷地创建Constraints方式,使用Layout Anchors。
1 | UIView *testView = [[UIView alloc] init]; |
相比于NSLayoutConstraint Class,Layout Anchors不仅提供了更易读的方法,而且,还加入了类型信息,可以在编译时可以报错,而不是等到运行时。例如:在leadingAnchor和widthAnchor之间创建Constraints时,会报错。
Visual Format Language
Visual Format Language使用一个类似ASCII-art类型的字符串来定义Constratints,其有以下的优缺点:
- Auto Layout打印在控制台中是Visual Format Language,因为编码如果使用Visual Format Language,将会更直观;
- Visual Format Language可以使用很简短的表达式,一次性创建多个Constraitns;
- Visual Format Language只能创建有效的Constraints;
- 一些特殊的Constraints无法通过Visual Format Language创建,例如Aspect Ratios;
- 编译器不会校验Visual Format Language的表达式,只能在运行时发现错误。
Visual Format Language的语法如下:
1 | UIView *testView = [[UIView alloc] init]; |
注意views要用NSDictionary定义好,在表达式中使用到的view:
1 | views:@{@"TestView":testView} |
matrics也是用NSDictionary定义好,在表达式中使用到的变量:
1 | metrics:@{@"Height":@40} |
表达式语法如下:
View用[]括起来表示,例如:
1 | [TestView] |
SuperVie用’|’表示,例如:
1 | |-[TestView]-| |
表达式前面用’H:’或者’V:’表示轴向,如果没有加上,默认是’H:’,例如:
1 | |-[TestView]-| |
标准间距(8px)用’-‘表示,例如:
1 | |-[TestView]-| |
表示TestView距离左右两边都是8px。
长度约束用’>=’、’==’、’<=’表示,例如:
1 | |-40-[TestView(>=50)]-40-| |
第一句表示TestView的Width至少为50,第二句表示TestView的Width等于TestView2的Width,第三句表示TestView的Width在70和100之间。
没有间距,可以直接并列,例如:
1 | [TestView][TestView2] |
优先级用‘@’加数字表示,例如:
1 | [TestView(100@20)] |
表示TestView的Width为100,优先级为20。
多个View的Constraints可以写在一条表达式中:
1 | |-[TestView]-[TestView2]-[TestView3(>=20)]-| |