前言
MagicNumber -> autoresizingMask -> autolayout
以上是纯手写代码所经历的关于页面布局的三个时期
在iphone1-iphone3gs时代 window的size固定为(320,480) 我们只需要简单计算一下相对位置就好了
在iphone4-iphone4s时代 苹果推出了retina屏 但是给了码农们非常大的福利:window的size不变
在iphone5-iphone5s时代 window的size变了(320,568) 这时autoresizingMask派上了用场(为啥这时候不用Autolayout? 因为还要支持ios5呗) 简单的适配一下即可
在iphone6+时代 window的width也发生了变化(相对5和5s的屏幕比例没有变化) 终于是时候抛弃autoresizingMask改用autolayout了(不用支持ios5了 相对于屏幕适配的多样性来说autoresizingMask也已经过时了)
简单介绍
Masonry是一个轻量级的布局框架,拥有自己的描述语法,采用更优雅的链式语法封装自动布局,简洁明了并具有高可读性,而且同时支持 iOS 和 Max OS X。Masonry是一个用代码写iOS或OS界面的库,可以代替Auto layout。
Masonry 源码:https://github.com/Masonry/Masonry
目录
Masonry配置
Masonry使用
Masonry实例
Masonry配置
- 推荐使用pods方式引入类库,pod ‘Masonry’
-定义以下两个宏,在使用Masonry框架时就不需要加mas_前缀了(定义宏一定要在引入Masonry.h文件之前).
//1. 对于约束参数可以省去"mas_"
#define MAS_SHORTHAND
//2. 对于默认的约束参数自动装箱
#define MAS_SHORTHAND_GLOBALS
- 引入头文件 #import "Masonry.h"
Masonry使用
Masonry支持的属性
@property (nonatomic, strong, readonly) MASConstraint *left;
@property (nonatomic, strong, readonly) MASConstraint *top;
@property (nonatomic, strong, readonly) MASConstraint *right;
@property (nonatomic, strong, readonly) MASConstraint *bottom;
@property (nonatomic, strong, readonly) MASConstraint *leading;
@property (nonatomic, strong, readonly) MASConstraint *trailing;
@property (nonatomic, strong, readonly) MASConstraint *width;
@property (nonatomic, strong, readonly) MASConstraint *height;
@property (nonatomic, strong, readonly) MASConstraint *centerX;
@property (nonatomic, strong, readonly) MASConstraint *centerY;
@property (nonatomic, strong, readonly) MASConstraint *baseline;
Masonry支持的方法
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;
/*
mas_makeConstraints 只负责新增约束 Autolayout不能同时存在两条针对于同一对象的约束 否则会报错
mas_updateConstraints 针对上面的情况 会更新在block中出现的约束 不会导致出现两个相同约束的情况
mas_remakeConstraints 则会清除之前的所有约束 仅保留最新的约束
三种函数善加利用 就可以应对各种情况了
*/
mas_makeConstraints 是给view添加约束,约束有几种,分别是边距,宽,高,左上右下距离,基准线。添加过约束后可以有修正,修正有offset(位移)修正和multipliedBy(倍率)修正。
语法一般是 make.equalTo or make.greaterThanOrEqualTo or make.lessThanOrEqualTo + 倍数和位移修正。
Masonry约束控件出现冲突的问题
当约束冲突发生的时候,我们可以设置view的key来定位是哪个view
redView.mas_key = @"redView";
greenView.mas_key = @"greenView";
blueView.mas_key = @"blueView";
若是觉得这样一个个设置比较繁琐,怎么办呢,Masonry则提供了批量设置的宏
MASAttachKeys
MASAttachKeys(redView,greenView,blueView); //一句代码即可全部设置
注意点
注意点1: 使用 mas_makeConstraints方法的元素必须事先添加到父元素的中,例如[self.view addSubview:view];
注意点2: mas_equalTo 和 equalTo 区别:mas_equalTo 比equalTo多了类型转换操作,一般来说,大多数时候两个方法都是 通用的,但是对于数值元素使用mas_equalTo。对于对象或是多个属性的处理,使用equalTo。特别是多个属性时,必须使用equalTo,例如 make.left.and.right.equalTo(self.view);
注意点3: 注意到方法with和and,这连个方法其实没有做任何操作,方法只是返回对象本身,这这个方法的左右完全是为了方法写的时候的可读性 。make.left.and.right.equalTo(self.view);和make.left.right.equalTo(self.view);是完全一样的,但是明显的加了and方法的语句可读性 更好点。
Masonry实例
-简单实例
// exp1: 中心点与self.view相同,宽度为400*400
-(void)exp1{
UIView *view = [UIView new];
[view setBackgroundColor:[UIColor redColor]];
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.size.mas_equalTo(CGSizeMake(400,400));
}];
}
//exp2: 上下左右边距都为10
-(void)exp2{
UIView *view = [UIView new];
[view setBackgroundColor:[UIColor redColor]];
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
// make.left.equalTo(self.view).with.offset(10);
// make.right.equalTo(self.view).with.offset(-10);
// make.top.equalTo(self.view).with.offset(10);
// make.bottom.equalTo(self.view).with.offset(-10);
}];
}
//exp3 让两个高度为150的view垂直居中且等宽且等间隔排列 间隔为10
-(void)exp3{
UIView *view1 = [UIView new];
[view1 setBackgroundColor:[UIColor redColor]];
[self.view addSubview:view1];
UIView *view2 = [UIView new];
[view2 setBackgroundColor:[UIColor redColor]];
[self.view addSubview:view2];
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.view.mas_centerY);
make.height.mas_equalTo(150);
make.width.mas_equalTo(view2.mas_width);
make.left.mas_equalTo(self.view.mas_left).with.offset(10);
make.right.mas_equalTo(view2.mas_left).offset(-10);
}];
[view2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.view.mas_centerY);
make.height.mas_equalTo(150);
make.width.mas_equalTo(view1.mas_width);
make.left.mas_equalTo(view1.mas_right).with.offset(10);
make.right.equalTo(self.view.mas_right).offset(-10);
}];
}
-Masonry高级使用例子
//高级布局练习 ios自带计算器布局
-(void)exp4{
//申明区域,displayView是显示区域,keyboardView是键盘区域
UIView *displayView = [UIView new];
[displayView setBackgroundColor:[UIColor blackColor]];
[self.view addSubview:displayView];
UIView *keyboardView = [UIView new];
[self.view addSubview:keyboardView];
//先按1:3分割 displView(显示结果区域)和 keyboardView(键盘区域)
[displayView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view.mas_top);
make.left.and.right.equalTo(self.view);
make.height.equalTo(keyboardView).multipliedBy(0.3f);
}];
[keyboardView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(displayView.mas_bottom);
make.bottom.equalTo(self.view.mas_bottom);
make.left.and.right.equalTo(self.view);
}];
//设置显示位置的数字为0
UILabel *displayNum = [[UILabel alloc]init];
[displayView addSubview:displayNum];
displayNum.text = @"0";
displayNum.font = [UIFont fontWithName:@"HeiTi SC" size:70];
displayNum.textColor = [UIColor whiteColor];
displayNum.textAlignment = NSTextAlignmentRight;
[displayNum mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.right.equalTo(displayView).with.offset(-10);
make.bottom.equalTo(displayView).with.offset(-10);
}];
//定义键盘键名称,?号代表合并的单元格
NSArray *keys = @[@"AC",@"+/-",@"%",@"÷"
,@"7",@"8",@"9",@"x"
,@"4",@"5",@"6",@"-"
,@"1",@"2",@"3",@"+"
,@"0",@"?",@".",@"="];
int indexOfKeys = 0;
for (NSString *key in keys){
//循环所有键
indexOfKeys++;
int rowNum = indexOfKeys %4 ==0? indexOfKeys/4:indexOfKeys/4 +1;
int colNum = indexOfKeys %4 ==0? 4 :indexOfKeys %4;
NSLog(@"index is:%d and row:%d,col:%d",indexOfKeys,rowNum,colNum);
//键样式
UIButton *keyView = [UIButton buttonWithType:UIButtonTypeCustom];
[keyboardView addSubview:keyView];
[keyView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[keyView setTitle:key forState:UIControlStateNormal];
[keyView.layer setBorderWidth:1];
[keyView.layer setBorderColor:[[UIColor blackColor]CGColor]];
[keyView.titleLabel setFont:[UIFont fontWithName:@"Arial-BoldItalicMT" size:30]];
//键约束
[keyView mas_makeConstraints:^(MASConstraintMaker *make) {
//处理 0 合并单元格
if([key isEqualToString:@"0"] || [key isEqualToString:@"?"] ){
if([key isEqualToString:@"0"]){
[keyView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(keyboardView.mas_height).with.multipliedBy(.2f);
make.width.equalTo(keyboardView.mas_width).multipliedBy(.5);
make.left.equalTo(keyboardView.mas_left);
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.9f);
}];
}if([key isEqualToString:@"?"]){
[keyView removeFromSuperview];
}
}
//正常的单元格
else{
make.width.equalTo(keyboardView.mas_width).with.multipliedBy(.25f);
make.height.equalTo(keyboardView.mas_height).with.multipliedBy(.2f);
//按照行和列添加约束,这里添加行约束
switch (rowNum) {
case 1:
{
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.1f);
keyView.backgroundColor = [UIColor colorWithRed:205 green:205 blue:205 alpha:1];
}
break;
case 2:
{
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.3f);
}
break;
case 3:
{
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.5f);
}
break;
case 4:
{
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.7f);
}
break;
case 5:
{
make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.9f);
}
break;
default:
break;
}
//按照行和列添加约束,这里添加列约束
switch (colNum) {
case 1:
{
make.left.equalTo(keyboardView.mas_left);
}
break;
case 2:
{
make.right.equalTo(keyboardView.mas_centerX);
}
break;
case 3:
{
make.left.equalTo(keyboardView.mas_centerX);
}
break;
case 4:
{
make.right.equalTo(keyboardView.mas_right);
[keyView setBackgroundColor:[UIColor colorWithRed:243 green:127 blue:38 alpha:1]];
}
break;
default:
break;
}
}
}];
}
}