Autolayout进阶之代码编写约束(一)

在我看来,Autolayout是开发神器,但是它也有局限之处。拿cell来举例,如果cell中的控件个数不确定,根据后台所给的数据来控制显示控件个数,那么Autolayout就不能简单的在xib上“拖”出来,而需要在代码中编写。这种情况在实际开发中是很常见的。我们再来看看原生代码的手写约束:

NSLayoutConstraint* leftConstraint = [NSLayoutConstraint constraintWithItem:logoImageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.0f];

//logoImageView右侧与父视图右侧对齐
NSLayoutConstraint* rightConstraint = [NSLayoutConstraint constraintWithItem:logoImageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0f constant:0.0f];

//logoImageView顶部与父视图顶部对齐
NSLayoutConstraint* topConstraint = [NSLayoutConstraint constraintWithItem:logoImageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f];

//logoImageView高度为父视图高度一半
NSLayoutConstraint* heightConstraint = [NSLayoutConstraint constraintWithItem:logoImageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:0.5f constant:0.0f];

//iOS 6.0或者7.0调用addConstraints
//[self.view addConstraints:@[leftConstraint, rightConstraint, topConstraint, heightConstraint]];

是不是很难记?和frame相比,也变得更抽象,代码量也更多。谁会愿意摆放一个控件写那么多代码?幸运的是,现在我们有很多第三方框架来帮我们简化这些代码。

Masonry和SDAutolayout


目前网上流行AutoLayout框架主要是Masonry和SDAutolayout。前者是我目前项目中常用的框架,主要是用block回调,并且将复杂的约束讲话成MASConstraintMaker进行约束封装。后者是声称比Masonry更简单易用的约束框架,采用链式编程的思想对约束进行封装,并能实现cell高度自适应。下面我们来看看具体的使用方法。

Masonry框架

  • Masonry是公认非常简洁优美的一款Autolayout框架
  • gitHub地址:https://github.com/SnapKit/Masonry
  • 推荐用cocoapods安装(如果不知道还是网上搜索下,开发必备)pod search Masonry
  • 非常适合拿来练手

首先#import "Masonry.h"导入头文件,然后就可以用代码进行约束编写:

//初始化一个view
UIView * redView = [[UIView alloc]init];
redView.backgroundColor = [UIColor redColor];
//然后将这个view添加到界面上
[self.view addSubview:redView];
//然后进行约束设置
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(self.view).offset(100);
    make.right.equalTo(self.view).offset(-200);
    make.top.equalTo(self.view).offset(100);
    make.height.mas_equalTo(100);
}];

先看这一段代码,首先创建了一个UIView,将背景色设成红色,然后进行约束设置。Masonry的命名都很直观,唯一要解释的可能就是这个make。我们可以理解成这个make就是redView本身,make.left.equalTo(self.view).offset(100);就是设置redView的左侧相对于self.view偏移量为100。这种思想和在xib上拖线的思想是一致的。再来看看设置自己本身高度的约束make.height.mas_equalTo(100);和上面一条唯一的区别就是mas_equalTo。还有一点需要注意的是.offset的值,如果前面是make.left(或者make.leading)和make.top,那么offset中设置的值为正数,如果是make.right(或者make.trailing)和make.bottom,那么offset中的值设成负数。
我们都知道,约束都有优先级。在Masonry语法中设置优先级也很简单,make.height.mas_equalTo(100).priority(500);只要在后面添上.priority(优先级)就行了,如果不添加,默认优先级为1000。

Autolayout进阶之代码编写约束(一)_第1张图片
单个红色控件约束效果

再看另外一个例子:

//初始化一个view
UIView * redView = [[UIView alloc]init];
redView.backgroundColor = [UIColor redColor];
UIView * greenView = [[UIView alloc]init];
greenView.backgroundColor = [UIColor greenColor];
//然后将这个view添加到界面上
[self.view addSubview:redView];
[self.view addSubview:greenView];

//然后进行约束设置
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
   
    make.left.equalTo(self.view).offset(100);
    make.right.equalTo(greenView.mas_left).offset(-50);
    make.top.equalTo(self.view).offset(100);
    make.height.mas_equalTo(100).priority(500);
}];

[greenView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.right.equalTo(self.view).offset(-30);
    make.top.equalTo(self.view).offset(100);
    make.height.mas_equalTo(100);
    make.width.mas_equalTo(100);
}];

这里要注意的是make.right.equalTo(greenView.mas_left).offset(-50);这个写法,中间的括号是greenView.mas_left,应该也很好理解。
效果:

Autolayout进阶之代码编写约束(一)_第2张图片
两个控件手写约束效果

关于mas_makeConstraintsmas_updateConstraintsmas_remakeConstraints的用法都是相同的,官方的API文档是这样描述的:

/**
 *  Creates a MASConstraintMaker with the callee view.
 *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing
 *
 *  @param block scope within which you can build up the constraints which you wish to apply to the view.
 *
 *  @return Array of created MASConstraints
 */
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;

/**
 *  Creates a MASConstraintMaker with the callee view.
 *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
 *  If an existing constraint exists then it will be updated instead.
 *
 *  @param block scope within which you can build up the constraints which you wish to apply to the view.
 *
 *  @return Array of created/updated MASConstraints
 */
- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;

/**
 *  Creates a MASConstraintMaker with the callee view.
 *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
 *  All constraints previously installed for the view will be removed.
 *
 *  @param block scope within which you can build up the    constraints which you wish to apply to the view.
 *
    *  @return Array of created/updated MASConstraints
 */
    - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;

总的来说,mas_makeConstraints就是在原基础上添加约束,mas_updateConstraints就是更新约束,mas_remakeConstraints就是先去除原有约束再添加约束

总结

  • 先把要添加约束的控件add到父视图上(addSubview)
  • 使用mas_makeConstraints添加约束,make可以设想成这个控件本身
  • 如果是添加左侧或者上侧的约束,offset用正数,如果添加右侧和下侧的约束,offset用负数
  • 设置本身的约束(height、width)用mas_equalTo
  • 如果两个平级控件之间设置约束,第二个控件要带上(mas_方向)

我是翻滚的牛宝宝,欢迎大家评论交流~

你可能感兴趣的:(Autolayout进阶之代码编写约束(一))