/* Create constraints explicitly. Constraints are of the form "view1.attr1 = view2.attr2 * multiplier + constant"
If your equation does not have a second view and attribute, use nil and NSLayoutAttributeNotAnAttribute.
*/
+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;这个类方法遵循一个计算公式:view1.attr1 = view2.attr2 * multiplier + constant" 如果没有参照的那个view(view2)的话就直接传nil和NSLayoutAttributeNotAnAttribute.主要用来 2个view之间的关系限制
比如说我想限制
button1.centerX = button2.centerX
[NSLayoutConstraint constraintWithItem:button1
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:button2
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0]
在创建约束之后,需要将其添加到作用的view上。UIView(当然NSView也一样)加入了一个新的实例方法:
-(void)addConstraint:(NSLayoutConstraint *)constraint; 用来将约束添加到view。在添加时唯一要注意的是添加的目标view要遵循以下规则:
对于两个同层级view之间的约束关系,添加到他们的父view上
* 对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
* 对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
可以通过-setNeedsUpdateConstraints和-layoutIfNeeded两个方法来刷新约束的改变,使UIView重新布局。这和CoreGraphic的-setNeedsDisplay一套东西是一样的~
举个例子来看看 self.view2 = [[UIView alloc] initWithFrame:self.view1.frame];
self.view2.backgroundColor = [UIColor redColor];
[self.view addSubview:self.view2];
// 这句话别忘了 要去掉系统的constraint
self.view2.translatesAutoresizingMaskIntoConstraints = NO;
// y对齐
NSLayoutConstraint *centerYConstrait = [NSLayoutConstraint constraintWithItem:self.view2
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.view1
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0];
// view1的右边 -10-view2的左边
NSLayoutConstraint *horizontalSpaceConstrait = [NSLayoutConstraint constraintWithItem:self.view2
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.view1
attribute:NSLayoutAttributeTrailing
multiplier:1
constant:10];
// 高度
NSLayoutConstraint *heightConstrait = [NSLayoutConstraint constraintWithItem:self.view2
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.view1
attribute:NSLayoutAttributeHeight
multiplier:1
constant:0];
// 宽度
NSLayoutConstraint *widthConstrait = [NSLayoutConstraint constraintWithItem:self.view2
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view1
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0];
[self.view addConstraints:@[centerYConstrait, horizontalSpaceConstrait, widthConstrait,heightConstrait]];
/* Create an array of constraints using an ASCII art-like visual format string.
*/
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;
先推荐http://constraints.icodeforlove.com/这个网站 牛b 好用
Github上一些好用的Autolayout第三方库
UIKit团队这次相当有爱,估计他们自己也觉得新加约束的API名字太长了,因此他们发明了一种新的方式来描述约束条件,十分有趣。这种语言是对视觉描述的一种抽象,大概过程看起来是这样的:
accept按钮在cancel按钮右侧默认间距处
最后使用VFL(Visual Format Language)描述变成这样:
[NSLayoutConstraint constraintsWithVisualFormat:@"[cancelButton]-[acceptButton]"
options:0
metrics:nil
views:viewsDictionary];
其中viewsDictionary是绑定了view的名字和对象的字典,对于这个例子可以用以下方法得到对应的字典:
UIButton *cancelButton = ...
UIButton *acceptButton = ...
viewsDictionary = NSDictionaryOfVariableBindings(cancelButton,acceptButton);
生成的字典为
{ acceptButton = ""; cancelButton = ""; }
在view名字后面添加括号以及连接处的数字可以赋予表达式更多意义,以下进行一些举例:
我要一个 左边距离self.view 100 顶部距离self.view 100 自身高度宽度都是200的view3
UIView *view3 = self.view2;
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-100-[view3]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3)]];
// align self.view2 from the top
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[view3]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3)]];
// width constraint
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view3(==200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3)]];
// height constraint
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[view3(==200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-100-[view3(==200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[view3(==200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view3)]];
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 100, 100)];
view1.backgroundColor = [UIColor redColor];
view1.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:view1];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 100, 100)];
view2.backgroundColor = [UIColor yellowColor];
view2.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:view2];
UIView *view3 = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 100, 100)];
view3.backgroundColor = [UIColor greenColor];
view3.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:view3];
NSString *verticalConstraintstr = @"H:|-space-[view1(viewWidth)]-(space)-[view2(viewWidth)]-(space)-[view3(viewWidth)]-(>=10)-|";
NSDictionary *views = @{@"view1":view1, @"view2": view2, @"view3":view3};
NSDictionary *metrics = @{@"viewWidth":@"20", @"space":@"10"};
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:verticalConstraintstr
options:NSLayoutFormatAlignAllCenterY
metrics:metrics
views:views];
[self.view addConstraints:verticalConstraints];
NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:view1 attribute:NSLayoutAttributeHeight multiplier:1.2 constant:0];
NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeHeight multiplier:1.2 constant:0];
NSLayoutConstraint *constraint3 = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:view3 attribute:NSLayoutAttributeHeight multiplier:1.2 constant:0];
[self.view addConstraints:@[constraint1, constraint2, constraint3]];
改天再说说scrollview 和 如何debug autolayout那一大堆警告