storyboard
-
警告
- 控件的frame不匹配所添加的约束
- 比如比如约束控件的宽度为100, 而控件现在的宽度是110
- 点击右下角的小三角,选择update frames即可
- 注意选择update frames的时候,有两个组
- selected views 当前被选择的views
- all views 所有views
- 如果当前的控件还没有添加完足够的约束,最好是一个一个更新frame,不然会发生控件消失的情况
- 控件的frame不匹配所添加的约束
-
错误
- 缺乏必要的约束
- 只约束了宽度和高度, 没有约束具体的位置
- 两个约束冲突
- 1个约束控件的宽度为100, 1个约束控件的宽度为110
- 缺乏必要的约束
代码创建Autolayout
步骤和注意点
- 不用再给view设置frame
- 首先关闭autoresizing自动转化成autolayout的功能
- 易错的:必须是把添加约束的控件设置成NO,而不是他得父控件
// 关闭Autoresizing转化成autolayout约束的功能
blueView.translatesAutoresizingMaskIntoConstraints = NO;
- 添加约束之前,一定要保证相关控件都已经在各自的父控件上
- 创建约束(官方文档)
// explicitly明确的.
// 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
* view1 :要约束的控件
* attr1 :约束的类型(做怎样的约束)
* relation :与参照控件之间的关系
* view2 :参照的控件
* attr2 :约束的类型(做怎样的约束)
* multiplier :乘数
* c :常量
-
约束规则
- 对于两个同层级view之间的约束关系,添加到它们的父view上
- 对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
- 对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
-
自动布局的核心计算公式
obj1.property1 =(obj2.property2 * multiplier)+ constant value
VFL
基本使用
- 创建一个高100,左右上都是20间距的view
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
// 1、禁用autoresizing转化成autolayout约束的功能
blueView.translatesAutoresizingMaskIntoConstraints = NO;
// 2、添加子控件到父控件上
[self.view addSubview:blueView];
// 3、创建约束
// 3.1 创建水平方向的约束
NSArray *constraintH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(blueView)];
// 3.2 创建竖直方向的约束
NSArray *constraintV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[blueView(100)]" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(blueView)];
// 4、添加约束
[self.view addConstraints:constraintH];
[self.view addConstraints:constraintV];
用法详解
NSArray *constraintH = [NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|"
options:kNilOptions metrics:nil
views:NSDictionaryOfVariableBindings(blueView)];
-
@"H:|-20-[blueView]-20-|"
- H:水平方向
- ‘|-20’ : 与父控件的左边间距是20
- ‘-20-|’: 与父控件的右边的间距是20
- [blueView] : 一般写成当前添加约束的控件,必须用[]包起来
-
如果options选项为空,最好使用kNilOptions(本质就是0)
-
metrics : 传入字典,用到的参数
-
views : 传入字典,表示给哪些控件添加约束
-
NSDictionaryOfVariableBindings(...),官方解释如下:
NSDictionaryOfVariableBindings(v1, v2, v3)
is equivalent to
[NSDictionary dictionaryWithObjectsAndKeys:v1, @"v1", v2, @"v2", v3, @"v3", nil];
- 创建两个等宽、等高、上、左、右间距都是20的view
- @"H:|-20-[blueView]-20-[redView(==blueView)]-20-| 意思是 blueView距离父控件左边20,距离redView右边20,redView的宽等于blueView并距离父控件右边20
- NSLayoutFormatAlignAllTop|NSLayoutFormatAlignAllBottom:TOP和button都相等,就是表示高相同
- @"V:|-20-[blueView(100)] blueView在竖直方向,距离顶部是20,高度是100
// 创建两个View,并关闭autoresizing转化成autolayout约束功能
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
blueView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:blueView];
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
redView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:redView];
// 创建水平约束数组
NSArray *constraintH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[blueView]-20-[redView(==blueView)]-20-|" options:NSLayoutFormatAlignAllTop|NSLayoutFormatAlignAllBottom metrics:nil views:NSDictionaryOfVariableBindings(blueView, redView)];
NSArray *constraintV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[blueView(100)]" options:kNilOptions metrics:nil views:NSDictionaryOfVariableBindings(blueView)];
[self.view addConstraints:constraintH];
[self.view addConstraints:constraintV];
Masonry
- 下载地址
- https://github.com/SnapKit/Masonry
- 目前最流行的Autolayout第三方框架
- 用优雅的代码方式编写Autolayout
- 省去了苹果官方恶心的Autolayout代码
- 大大提高了开发效率
第三方框架Masonry基本使用
- 下载框架后,解压
- 然后打开其解压目录中的 Masonry.xcworkspace
- 一般在其Masonry.xcworkspace中可以找到实例程序,运行实例程序,看看效果,并根据实例程序,选择自己想要的功能,并查看如何实现
如何Masonry用在自己的项目中
- 将与框架名相同(Masonry)的那个文件夹导入自己的项目中
- 导入主头文件,Masonry.h
- 添加宏,切记:这两个宏一定要在Masonry.h的前面
//define this constant if you want to use Masonry without the 'mas_' prefix
// 只要添加了这个宏,就不用带mas_前缀
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
// 只要添加了这个宏,equalTo就等价于mas_equalTo
#define MAS_SHORTHAND_GLOBALS
// 这个头文件一定要放在上面两个宏的后面
#import "Masonry.h"
- 添加约束的方法
// 这个方法只会添加新的约束
[view makeConstraints:^(MASConstraintMaker *make) {
}];
// 这个方法会将以前的所有约束删掉,添加新的约束
[view remakeConstraints:^(MASConstraintMaker *make) {
}];
// 这个方法将会覆盖以前的某些特定的约束
[view updateConstraints:^(MASConstraintMaker *make) {
}];
- 约束的类型
1.尺寸:widthheightsize
2.边界:leftleading
ight railing opottom
3.中心点:centercenterXcenterY
4.边界:edges