前言
•本文为iOS开发AutoLayout的总结记录和一些适配的经验,主要讲述当前使用比较多的系统自适应的方式,特别是tableView的cell的高度自适应(能用tableview完成的界面,都不用其它UI)。适应方式包括:
1.NSLayoutConstraint
2.Masonry
3.XIB
4.计算Frame
5.数据LayoutModel概念
其中,前三种都是一样的,只是不同的方式,Masonry封装了NSLayoutConstraint,点语法更加简便易用。
内容
首先备注一下,
View自适应,需要把View的translatesAutoresizingMaskIntoConstraints设置为NO,XIB会自动设置,可以考虑在基类设置。
1.NSLayoutConstraint
NSLayoutConstraint是系统类,用于添加约束,在添加约束前,必须要先把view添加到父view上再进行约束。约束一般为4个约束,最基本的是原点+宽高,后面衍生出相对距离,居中,齐平等条件,再后来就是约束的优先级设置,优先级有 至少,最多,约束冲突优先级等设置,基本上满足了所有的UI设计!开发过程中需要想象约束条件。以下举个例子
图中有5个约束(比4个多),这个cell如果设置了自适应高度,那么图片的4个边距是一定,并且图片的高度是一定比某个值大。
那么按照上面图,我们对应NSLayoutConstraint的代码如下:
[self.content addConstraint:[NSLayoutConstraint constraintWithItem:self.content attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeLeft multiplier:1.0f constant:170]]; [self.content addConstraint:[NSLayoutConstraint constraintWithItem:self.content attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeTop multiplier:1.0f constant:5]]; [self.content addConstraint:[NSLayoutConstraint constraintWithItem:self.content attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeRight multiplier:1.0f constant:-5]]; [self.content addConstraint:[NSLayoutConstraint constraintWithItem:self.content attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-5]]; [self.content addConstraint:[NSLayoutConstraint constraintWithItem:self.content attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self.contentView attribute:NSLayoutAttributeHeight multiplier:1.0f constant:90]];
5个NSLayoutConstraint对应5图内5条线,代码看似很多,其实内容很少,仔细会发现有很多重复的代码!
为了将复杂的东西简单化,直观化,Masonry就这样出现了。
2.Masonry
Masonry是链式编程标志性库,链式编程把一个个方法调用使用了”点”方法来调用,理解是,将代码区块化并且区块代码返回当前操作对象用于调用下一个区块代码!
利用了2个知识点:1.block的代码块封装,2. Get方法(“点”方法)!
最简单的block封装结构如下:
//第一种方式,直接声明block,看着比较复杂 - (Person *(^)(void))sleep{ Person * (^sleepBlock)(void) = ^(void){ NSLog(@"-----我在睡觉----"); return self; }; return sleepBlock; } //第二种方式,先定义block,再来设置方法内容,比较清晰 typedef Person *_Nullable(^noDataBlock)(void); - (noDataBlock)wakeup{ noDataBlock block = ^{ NSLog(@"-----我起床了----"); return self; }; return block; }
有兴趣的小伙伴可以自行百度,链式编程代码比较美观,跟JAVA和Python的语法有点像,挺好!
Masonry核心代码实际是封装了NSLayoutConstraint,所以,如果我们觉得苹果的繁琐&&啰嗦,不妨使用Masonry,思想和想象的方式是一样的,例如针对上图的约束,我们用Masonry做一遍,代码如下:
[self.content mas_makeConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(weakSelf.view.mas_left).mas_offset(170); make.top.mas_equalTo(weakSelf.view.mas_top).mas_offset(5); make.bottom.mas_equalTo(weakSelf.view.mas_bottom).mas_offset(-5); make.right.mas_equalTo(weakSelf.view.mas_right).mas_offset(-5); make.height.mas_greaterThanOrEqualTo(90); }];
对比下效果是不是觉得很简洁!
当然,Masonry还有一些优先级的设置,例如上面的大于等于90高度的设置,如果要设置优先级,如下
make.height.mas_greaterThanOrEqualTo(90).priorityMedium();
Masonry能满足你想要的约束
以上方式为纯代码方式,内容多了编写起来也是挺费劲,从动态加载数据和继承方面来说,代码编写比较习惯的理解!
当界面是静态界面并且没有继承(普通业务界面一般不被继承),苹果给我们一个很直观,很渐变的方式编写UI,并且约束直观,效率高! 这就是XIB。
3.XIB
XIB的关联这里不描写步骤,思想与上面描述的也是一样,一行代码描写了一条线!
喜欢它快和直观,跟Android的UI配置文件XML很相似!自适应高度或宽度的时候不要限制高度或宽度等于某个常数并且是最高优先级即可!
XIB是静态页面适配首选!
总结:以上是3种约束的方式,归根到底是一种方法,3种设置方法,设置的约束比较固定,难免会出现大小屏间距,高宽一模一样的问题! 这主要原因是我们设置约束都是一些常识!
针对以上的问题,有的人会做一个Frame管理类来计算对应屏幕对应的数值,原理是根据屏幕宽高和设计稿使用的屏幕宽高计算出一个比例来实现获取对应的值,简单公式如下
resultWidth = designWidth * [UIScreen mainScreen].bounds.size.width/designFrameWidth(例如:375)
以上只是例子,有很多种计算!
4.计算Frame
—–未完, 待续—-