第三方库Masonry自动布局AutoLayout使用

来源:互联网 发布:好麦道 知乎 编辑:程序博客网 时间:2024/05/16 10:32

布局:

   1. 放在哪  坐标  CGPoint(x, y)
   2. 有多大  尺寸  CGSize(width, height)


布局方式:

   1.绝对布局(FrameLayout)也称 坐标布局
   2.自动布局(AutoLayout)

FrameLayout(绝对布局)

     方式:
      一种方式可以直接使用frame来定义坐标和宽高,
      一种方式是 先使用bounds 属性赋值确定尺寸(宽, 高),然后使用center确定坐标(x, y)      ① view.frame = [位置,尺寸];
      ② view.bounds = CGRect
         view.center = (x, y) 
     优点:直观、简单
     缺点:屏幕适配难度大,需要复杂的几何运算
     基于:基于frame布局

AutoLayout(自动布局)

   方式:自动布局有很多方式,可以使用iOS系统本身的(自带的API太繁杂)、也可以使用github上的第三方库(Masonry)
   优点:解决了不同分辨率和屏幕尺寸下view的适配问题,另外也简化了旋转时view的位置的定义
   基于:基于约束(Constraint)布局

自动布局AutoLayout简介:

自动布局是一种基于约束的,描述性的布局系统,使用约束条件来描述布局,使用AutoLayout布局就和坐标没有任何关系了,
view的位置会根据约束条件自动计算出frame,最大好处是一举解决了不同分辨率和屏幕尺寸下view的适配问题,另外也简化了旋转时view的位置的定义。
自动布局是基于约束的,和坐标没有半点关系。系统将根据不同的约束来自动计算控件的具体位置,最终也将使用绝对布局!只不过暴露给开发者的是一些约束
如果使用自动布局而不加任何约束,那么系统会自动添加约束

自动布局的使用方式:

1. 可以在XIB或storybord上直接在界面上添加约束
右下角一组四个按钮:Stack、Align对齐、Pin定位、Resolve Auto Layout Issues

Update Frames
Add 1 Constraint

2. 也可以使用纯代码来添加约束

对于布局技术趋势: 以后的趋势将会逐渐使用 自动布局AutoLayout,而使用CGRectMake的方式将逐渐淘汰掉


界面操作方式:


-------


自动布局第三方库 Masonry(github 一万多个星星 发音:美森瑞)

该库的特点:采用链式语法, 易读


首先了解一下Masonry库的几个常用的类

View+MASAdditions.h@interface MAS_VIEW (MASAdditions)@property (nonatomic, strong, readonly) MASViewAttribute *mas_left;    // x坐标@property (nonatomic, strong, readonly) MASViewAttribute *mas_top;     // y坐标@property (nonatomic, strong, readonly) MASViewAttribute *mas_right;   // x + width@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottom;  // y + height@property (nonatomic, strong, readonly) MASViewAttribute *mas_leading;@property (nonatomic, strong, readonly) MASViewAttribute *mas_trailing;@property (nonatomic, strong, readonly) MASViewAttribute *mas_width;   // width@property (nonatomic, strong, readonly) MASViewAttribute *mas_height;  // height@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX; // (x + width)/2@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY; // (y + height)/2@property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline;@property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr);// 生成约束- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;// 更新常量约束- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;// 重新生成约束(先删除所有约束,再重新生成新的约束)- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;@end

@interface MASConstraintMaker : NSObject@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;@property (nonatomic, strong, readonly) MASConstraint *edges;@property (nonatomic, strong, readonly) MASConstraint *size;@property (nonatomic, strong, readonly) MASConstraint *center;@end

@interface MASConstraint : NSObject- (MASConstraint * (^)(id attr))equalTo;                // equalTo(superView)- (MASConstraint * (^)(id attr))greaterThanOrEqualTo;- (MASConstraint * (^)(id attr))lessThanOrEqualTo;- (MASConstraint * (^)(id attr))mas_equalTo;//mas_equalTo(NSNumber|CGPoint|CGSize|UIEdgeInsets)- (MASConstraint * (^)(id attr))mas_greaterThanOrEqualTo;- (MASConstraint * (^)(id attr))mas_lessThanOrEqualTo;- (MASConstraint * (^)(id offset))mas_offset;             - (MASConstraint * (^)(CGFloat offset))offset;- (MASConstraint * (^)(CGSize offset))sizeOffset;- (MASConstraint * (^)(CGPoint offset))centerOffset;- (MASConstraint *)with;- (MASConstraint *)and;- (MASConstraint *)left;- (MASConstraint *)top;- (MASConstraint *)right;- (MASConstraint *)bottom;- (MASConstraint * (^)(MASEdgeInsets insets))insets;- (MASConstraint *)leading;- (MASConstraint *)trailing;- (MASConstraint *)width;- (MASConstraint *)height;- (MASConstraint *)centerX;- (MASConstraint *)centerY;- (MASConstraint *)baseline;@end


对Masonry的理解

使用Masonry时必须先添加子视图addSubview,然后再创建约束mas_makeConstraints 


常用函数:

equalTo(superView)
mas_equalTo(NSNumber|CGPoint|CGSize|UIEdgeInsets)
insets(UIEdgeInsets(top, left, bottom, right))
offset(CGFloat)

有意思的地方是and和with 其实这两个函数什么事情都没做,通过这两个函数进行链式语法的链接,更加的符合人们的语言习惯
- (MASConstraint *)with {
    return self;
}
- (MASConstraint *)and {
    return self;
}


约束:

    无论约束怎么组合都必须能让系统计算出 坐标 和 尺寸, 约束过多或不足都会影响系统来计算坐标和尺寸的
在使用Masonry来约束时,首先先想一下使用坐标是怎么计算的,让后 让绝对布局方式转为自动布局方式

约束指定一般使用一下方式:
make.约束.equalTo(superView)[.with.offset(CGFloat)]
make.约束.mas_equalTo(NSNumber|CGPoint|CGSize|UIEdgeInsets)

约束组合方式

一组约束必须能计算出坐标值(x, y)和尺寸(width, height)

// 这两个约束是完全一样的,可以带superView.mas_xxx 也可以省略直接父视图 superView

make.left.greaterThanOrEqualTo(label);
make.left.greaterThanOrEqualTo(label.mas_left);

自动布局允许宽度和高度设置为常量值。如果你想设置视图有一个最小和最大宽度也可以通过约束实现:
//width >= 200 && width <= 400
make.width.greaterThanOrEqualTo(@200);
make.width.lessThanOrEqualTo(@400)

指定常量值
make.top.mas_equalTo(42);
make.height.mas_equalTo(20);
make.size.mas_equalTo(CGSizeMake(50, 100));
make.edges.mas_equalTo(UIEdgeInsetsMake(10, 0, 10, 0));
make.left.equalTo(view).mas_offset(UIEdgeInsetsMake(10, 0, 10, 0));

edges
// make top, left, bottom, right equal view2
make.edges.equalTo(view2);

// make top = superview.top + 5, left = superview.left + 10,
//      bottom = superview.bottom - 15, right = superview.right - 20
make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20))

size
// make width and height greater than or equal to titleLabel
make.size.greaterThanOrEqualTo(titleLabel)

// make width = superview.width + 100, height = superview.height - 50
make.size.equalTo(superview).sizeOffset(CGSizeMake(100, -50))

center
// make centerX and centerY = button1
make.center.equalTo(button1)

// make centerX = superview.centerX - 5, centerY = superview.centerY + 10
make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10))

组合1: 直接指明坐标和尺寸

center  (坐标)     equalTo(superView)
size (尺寸)  mas_equalTo(CGSize)

组合2:通过设定 上下左右边距 四个方向的边距 来计算控件的坐标

(通过相对于父视图的 顶部边距,左边距来计算坐标) 通过(顶部 底部 边距来计算高度,左右边距来计算宽度)
edges              insets(UIEdgeInsets(top, left, bottom, right))

组合3:(left right  top height)

通过左右边距left right确定宽度和x坐标,通过上边距top确定y坐标,通过高度height确定高度

组合4:(left, top, right) 

       对于UILabel 而言 不需要高度,高度是由字体,字号计算出来的


示例程序:

#import "MainViewController.h"#import "Masonry.h"#define WS(weakSelf)  __weak __typeof(&*self)weakSelf = self;@interface MainViewController ()@end@implementation MainViewController- (void)viewDidLoad {    [super viewDidLoad];        self.title = @"Masonry";    self.view.backgroundColor = [UIColor whiteColor];        [self initCenterView];}- (void)initCenterView {        // -------------------superView---------------------    UIView * superView = [[UIView alloc] init];    superView.backgroundColor = [UIColor blackColor];    [self.view addSubview:superView];        WS(this);    [superView mas_makeConstraints:^(MASConstraintMaker *make) {        make.center.equalTo(this.view);        make.size.mas_equalTo(CGSizeMake(300, 300));    }];        // 让一个view略小于其superView(边距为10)-------------------centerView---------------------    UIView * centerView = [UIView new];    centerView.backgroundColor = [UIColor redColor];    [superView addSubview:centerView];    [centerView mas_makeConstraints:^(MASConstraintMaker *make) {        // 以下三种方式完全一样//        make.edges.equalTo(superView).insets(UIEdgeInsetsMake(10, 10, 10, 10));   // edges是指的边缘填充,都是正数值        //        make.top.equalTo(superView).with.offset(10);                  // y坐标在父视图y坐标的基础上 加 10px//        make.left.equalTo(superView).with.offset(10);                 // x坐标在父视图x坐标的基础上 加 10px//        make.bottom.equalTo(superView).with.offset(-10);              // 子视图的高度相对于父视图的高度 减去10px//        make.right.equalTo(superView).with.offset(-10);               // 子视图的宽度相对于父视图的宽度 减去10px                make.top.left.bottom.and.right.equalTo(superView).insets(UIEdgeInsetsMake(10, 10, 10, 10));    }];            // 让两个高度为150的view垂直居中且等宽且等间隔排列 间隔为10(自动计算其宽度)    // -------------------orangeView1---------------------    UIView * orangeView1 = [UIView new];    orangeView1.backgroundColor = [UIColor orangeColor];    [centerView addSubview:orangeView1];        UIView * orangeView2 = [UIView new];    orangeView2.backgroundColor = [UIColor orangeColor];    [centerView addSubview:orangeView2];        int padding = 10;    int height = 250;    [orangeView1 mas_makeConstraints:^(MASConstraintMaker *make) {        make.centerY.mas_equalTo(centerView.mas_centerY);               // 纵向垂直居中, 确定y坐标        make.height.mas_equalTo(height);                                // 确定高度       height        make.left.equalTo(centerView.mas_left).with.offset(padding);    // 确定 x坐标        make.right.equalTo(orangeView2.mas_left).with.offset(-padding); // 右边距为 10        make.width.equalTo(orangeView2);                                // 确定宽度    }];            // -------------------orangeView2---------------------    [orangeView2 mas_makeConstraints:^(MASConstraintMaker *make) {        make.centerY.mas_equalTo(centerView.mas_centerY);               // 垂直居中        make.height.mas_equalTo(height);                                // 确定高度        make.left.equalTo(orangeView1.mas_right).with.offset(padding);  // 左边距:第一个视图的右边x坐标 +10        make.right.equalTo(centerView.mas_right).with.offset(-padding); // 又边距:父视图的x坐标 -10        make.width.equalTo(orangeView1);                                // 确定宽度    }];                                                                                                                                              UILabel * titleLabel = [UILabel new];    titleLabel.backgroundColor = [UIColor whiteColor];    titleLabel.numberOfLines = 0;    titleLabel.text = @"autolayout hello ----------------";    titleLabel.tintColor = [UIColor blackColor];    [orangeView1 addSubview:titleLabel];    [titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {                                                                               // 对于UILabel无需设置高度,因为高度是由字体,字号计算出来的      make.left.equalTo(orangeView1).offset(10);      make.top.equalTo(orangeView1).offset(10);      make.right.equalTo(orangeView1).offset(-10);    }];                                                                                                                                                      // 在UIScrollView顺序排列一些view并自动计算contentSize----------------------------------------------------    UIScrollView * scrollView = [UIScrollView new];    scrollView.backgroundColor = [UIColor whiteColor];    [orangeView2 addSubview:scrollView];        [scrollView mas_makeConstraints:^(MASConstraintMaker *make) {        make.edges.equalTo(orangeView2).with.insets(UIEdgeInsetsMake(5, 5, 5, 5));    }];        UIView * containerView = [UIView new];    containerView.backgroundColor = [UIColor blackColor];    [scrollView addSubview:containerView];    [containerView mas_makeConstraints:^(MASConstraintMaker *make) {        make.edges.equalTo(scrollView);        make.width.equalTo(scrollView); // ??????????    }];        int count = 10;    UIView * lastView = nil;    for (int i = 1; i < count; i++) {        UIView * subView = [UIView new];        subView.backgroundColor = [UIColor colorWithHue:(arc4random() % 256 / 256.0)                                             saturation:(arc4random() % 128 / 256.0) + 0.5                                             brightness:(arc4random() % 128 / 256.0) + 0.5                                                  alpha:1];        [containerView addSubview:subView];        [subView mas_makeConstraints:^(MASConstraintMaker *make) {            make.left.and.right.equalTo(containerView);            make.height.mas_equalTo(@(20 * i));            if (lastView != nil) {                make.top.mas_equalTo(lastView.mas_bottom);            } else {                make.top.mas_equalTo(containerView.mas_top);            }                    }];                lastView = subView;    }        [containerView mas_makeConstraints:^(MASConstraintMaker *make) {        make.bottom.equalTo(lastView.mas_bottom);    }];    }@end

运行效果如果:


Interface Builder AutoLayout(以下两篇文章写的很好,应认真看一下)

开始iOS 7中自动布局教程(一) http://www.cocoachina.com/industry/20131203/7462.html
开始iOS 7中自动布局教程(二) http://www.it165.net/pro/html/201409/22410.html#

0 0
原创粉丝点击