最近在学习iOS的布局,在storyboard里,确定布局的思路:
1、确定能确定的;
2、无法确定的,看看是否可以想办法和其他控件关联起来,再根据关系来确定能确定的位置.
例子:实现如下图的布局
过程:
1、确定能确定的;
左上角的View,左边和上边距离父view的距离都是0(当然,这里假设了view的宽度和高度都是100)
设置完成后,点击Add 4 Constraints即可,现在界面如下所示;
左边View Controller Scene后面有个黄色图标,该图标的意思是警告的意思,是最终的位置和目前位置不匹配,更新一下即可,效果如下:
其他3个的设置过程大概也是一样,不一一设置了.
2、无法确定的,看看是否可以想办法和其他控件关联起来,再根据关系来确定能确定的位置.
例子效果图:
效果图中的两个view的高度和宽度永远相等(这里我设置高度为50),距离父view左边、右边、下边间距和2个view之间的间距相等.都是30.
这种效果可以确定的是红色view离父view的左边和底部的位置都是固定的,都为30,设置如:
这里要注意的是设置底部时要注意距离的是父view还是Bottom Layout Guide了,当然顶部也是需要注意的。(其实就是需要注意参照物)
在这里,会发现设置完后左上角会有个红色的图标,这说明还有位置没有设置约束或者有约束冲突。
蓝色view离父view的右边和底部的位置都是固定的,也是30:
那么现在问题来了,只确定这2个位置,是无法给这两个view来确定最终位置的。
在这里,由于两个view的宽度都是相等的,而且间距也是固定了,那么是否就可以最终固定下这两个view的位置了呢?
先选中两个view,然后设置宽度相等:
接着选中任意一个view,设置间距,这里我选择的是红色的view来设置的
然后更新下frame即可:
可以选择选中的view,也可以选择所有的,点击Update Frames后,最终结果如下图:
以上为在storyboard里使用Autolayout来布局的一些过程,其他的也差不多,就不一一讲述了。
使用代码的形式:
在添加时唯一要注意的是添加的目标view要遵循以下规则:
- 对于两个同层级view之间的约束关系,添加到他们的父view上
-
对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
- 对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
- (void)addConstraint:(NSLayoutConstraint *)constraint;
- (void)addConstraints:(NSArray *)constraints;
1 +(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
obj1.property1 =(obj2.property2 * multiplier)+ constant value
上面第二个效果图的代码写法如下:
1 //添加一个红色view 2 UIView *redView = [[UIView alloc] init]; 3 redView.backgroundColor = [UIColor redColor]; 4 redView.translatesAutoresizingMaskIntoConstraints = NO; 5 [self.view addSubview:redView]; 6 7 8 //添加一个蓝色view 9 UIView *blueView = [[UIView alloc] init]; 10 blueView.backgroundColor = [UIColor blueColor]; 11 blueView.translatesAutoresizingMaskIntoConstraints = NO; 12 [self.view addSubview:blueView]; 13 14 //给红色view添加约束 15 NSLayoutConstraint *redLeft = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:30.0]; 16 [self.view addConstraint:redLeft]; 17 18 NSLayoutConstraint *redBottom = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-30.0]; 19 [self.view addConstraint:redBottom]; 20 21 NSLayoutConstraint *redHeight = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:0.0 constant:50.0]; 22 [redView addConstraint:redHeight]; 23 24 //给蓝色view添加约束 25 NSLayoutConstraint *blueRight = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-30.0]; 26 [self.view addConstraint:blueRight]; 27 28 NSLayoutConstraint *blueBottom = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-30.0]; 29 [self.view addConstraint:blueBottom]; 30 31 NSLayoutConstraint *blueHeight = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:0.0 constant:50.0]; 32 [blueView addConstraint:blueHeight]; 33 34 NSLayoutConstraint *blueWidth = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]; 35 [self.view addConstraint:blueWidth]; 36 37 NSLayoutConstraint *blueLeft = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeRight multiplier:1.0 constant:30.0]; 38 [self.view addConstraint:blueLeft];
看完使用代码来自动布局是不是有种坑爹的感觉,好长好臭~~别急,苹果还给我们提供了另外一种方式VFL:
VFL的使用:
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;
1 //初始化两个view 2 UIView *redView = [[UIView alloc] init]; 3 redView.backgroundColor = [UIColor redColor]; 4 redView.translatesAutoresizingMaskIntoConstraints = NO; 5 [self.view addSubview:redView]; 6 7 UIView *blueView = [[UIView alloc] init]; 8 blueView.backgroundColor = [UIColor blueColor]; 9 blueView.translatesAutoresizingMaskIntoConstraints = NO; 10 [self.view addSubview:blueView]; 11 12 //设置水平方向上的约束,代表的意思是blueView离父view左边间距为30,和redView的间距为30,redView和父view的右间距为30,redView的宽度和blueView的宽度相等 13 NSString *hVFL = @"H:|-30-[blueView]-30-[redView(==blueView)]-30-|"; 14 NSArray *hCons = [NSLayoutConstraint constraintsWithVisualFormat:hVFL options:NSLayoutFormatAlignAllBottom | NSLayoutFormatAlignAllTop metrics:nil views:@{@"blueView":blueView,@"redView":redView}]; 15 [self.view addConstraints:hCons]; 16 17 //设置垂直方向上的约束,代表的意思是blueView的高度是50,离父view的底部间距是30 18 NSString *vVFL = @"V:[blueView(50)]-30-|";//@"V:-30-[blueView(50)]",这里的30代表离父类的顶部间距是30 19 NSArray *vCons = [NSLayoutConstraint constraintsWithVisualFormat:vVFL options:0 metrics:nil views:@{@"blueView":blueView}]; 20 [self.view addConstraints:vCons];
还是附上效果图吧: