最近在学习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上
实现Autolayout的步骤
利用NSLayoutConstraint类创建具体的约束对象
添加约束对象到相应的view上
- (void)addConstraint:(NSLayoutConstraint *)constraint;
- (void)addConstraints:(NSArray *)constraints;
代码实现Autolayout的注意点
要先禁止autoresizing功能,设置view的下面属性为NO
view.translatesAutoresizingMaskIntoConstraints = NO;
添加约束之前,一定要保证相关控件都已经在各自的父控件上
不用再给view设置frame
一个NSLayoutConstraint对象就代表一个约束
创建约束对象的常用方法
1 +(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
view1 :要约束的控件
attr1 :约束的类型(做怎样的约束)
relation :与参照控件之间的关系
view2 :参照的控件
attr2 :约束的类型(做怎样的约束)
multiplier :乘数
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?
VFL全称是Visual Format Language,翻译过来是“可视化格式语言”
VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言:
VFL示例:
H:[cancelButton(72)]-12-[acceptButton(50)]
canelButton宽72,acceptButton宽50,它们之间间距12
H:[wideView(>[email protected])]
wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)
V:[redBox][yellowBox(==redBox)]
竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox
H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)
VFL的使用:
使用VFL来创建约束数组
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;
format :VFL语句
opts :约束类型
metrics :VFL语句中用到的具体数值
views :VFL语句中用到的控件
上面第二个效果图的VFL代码的写法如下:
1 // 1.添加两个控件 2 UIView *blueView = [[UIView alloc] init]; 3 blueView.backgroundColor = [UIColor blueColor]; 4 blueView.translatesAutoresizingMaskIntoConstraints = NO; 5 [self.view addSubview:blueView]; 6 7 UIView *redView = [[UIView alloc] init]; 8 redView.backgroundColor = [UIColor redColor]; 9 redView.translatesAutoresizingMaskIntoConstraints = NO; 10 [self.view addSubview:redView]; 11 12 // 2.添加约束 13 // 2.1.水平方向约束 14 NSString *hVFL = @"H:|-30-[blueView]-30-[redView(==blueView)]-30-|"; 15 NSArray *hCons = [NSLayoutConstraint constraintsWithVisualFormat:hVFL options:NSLayoutFormatAlignAllBottom | NSLayoutFormatAlignAllTop metrics:nil views:@{@"blueView" : blueView, @"redView" : redView}]; 16 [self.view addConstraints:hCons]; 17 18 // 2.2.垂直方向约束 19 NSString *vVFL = @"V:[blueView(50)]-30-|"; 20 NSArray *vCons = [NSLayoutConstraint constraintsWithVisualFormat:vVFL options:0 metrics:nil views:@{@"blueView" : blueView}]; 21 [self.view addConstraints:vCons];
还是附上效果图吧: