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。

单个红色控件约束效果

再看另外一个例子:

//初始化一个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,应该也很好理解。
效果:

两个控件手写约束效果

关于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_方向)

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容