Masonry简单使用

作者: 多飞 | 来源:发表于2016-04-25 14:39 被阅读444次

    一、 Masonry简介:

    1)Masonry是一个轻量级的布局框架,拥有自己的描述语法,采用更优雅的链式语法封装自动布局,简洁明了并具有相当高的可读性,而且同时支持 iOS 和 Max OS X。Masonry是一个用代码写iOS或OS界面的库,可以代替Auto layout
    2)使用Masonry不需要设置translatesAutoresizingMaskIntoConstraints的属性设置为NO.

    在VFL中:
    如果是从代码层面开始使用Autolayout,需要对使用的View的>translatesAutoresizingMaskIntoConstraints的属性设置为NO.
    即可开始通过代码添加Constraint,否则View还是会按照以往的>autoresizingMask进行计算.
    而在Interface Builder中勾选了Ues Autolayout,IB生成的控件的>translatesAutoresizingMaskIntoConstraints属性都会被默认设置NO.

    二、 Masonry属性:

    Masonry NSAutoLayout 说明
    left NSLayoutAttributeLeft 左侧
    top NSLayoutAttributeTop 上侧
    right NSLayoutAttributeRight 右侧
    bottom NSLayoutAttributeBottom 下侧
    leading NSLayoutAttributeLeading 首部
    trailing NSLayoutAttributeTrailing 尾部
    width NSLayoutAttributeWidth
    height NSLayoutAttributeHeight
    centerX NSLayoutAttributeCenterX 横向中点
    centerY NSLayoutAttributeCenterY 纵向中点
    baseline NSLayoutAttributeBaseline 文本基线

    三、方法

    1) 首先在Masonry中能够添加autolayout约束有三个函数
    - (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 则会清除之前的所有约束 仅保留最新的约束
    三种函数善加利用 就可以应对各种情况了
    */
    
    2) 其次 equalTo 和 mas_equalTo的区别在哪里呢? 其实 mas_equalTo是一个MACRO
    #define mas_equalTo(...)                 equalTo(MASBoxValue((__VA_ARGS__)))
    #define mas_greaterThanOrEqualTo(...)    greaterThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
    #define mas_lessThanOrEqualTo(...)       lessThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
    #define mas_offset(...)                  valueOffset(MASBoxValue((__VA_ARGS__)))
    

    可以看到 mas_equalTo只是对其参数进行了一个BOX操作(装箱) MASBoxValue的定义具体可以看看源代码 太长就不贴出来了

    所支持的类型 除了NSNumber支持的那些数值类型之外 就只支持CGPoint CGSize UIEdgeInsets

    3) and和with语法

    and和with 其实这两个函数什么事情都没做
    - (MASConstraint *)with {
    return self;
    }
    - (MASConstraint *)and {
    return self;
    }

    注意:在block中self需要进行弱引用self为什么要弱引用?)先介绍一个MACRO:
    #define WS(weakSelf) __weak __typeof(&*self)weakSelf = self;

    例1
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    WS(ws);//将self弱引用
    UIView *sv = [UIView new];
    [sv showPlaceHolder];
    sv.backgroundColor = [UIColor blackColor];
    [self.view addSubview:sv];
    //居中显示
    [sv mas_makeConstraints:^(MASConstraintMaker *make) {
        make.center.equalTo(ws.view);
        make.size.mas_equalTo(CGSizeMake(300, 300));
    }];
     
    }
    

    例1效果图:


    例1
    例2 让一个view略小于其superView(边距为10)
     UIView *sv1 = [UIView new];
        [sv1 showPlaceHolder];
        sv1.backgroundColor = [UIColor redColor];
        [sv addSubview:sv1];
        [sv1 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(sv).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
     
    /* 等价于
    make.top.equalTo(sv).with.offset(10);
    make.left.equalTo(sv).with.offset(10);
    make.bottom.equalTo(sv).with.offset(-10);
    make.right.equalTo(sv).with.offset(-10);
    */
     
    /* 也等价于
    make.top.left.bottom.and.right.equalTo(sv).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
    */
    }];
    

    例2效果图:

    例2

    可以看到 edges 其实就是top,left,bottom,right的一个简化 分开写也可以 一句话更省事
    那么为什么bottom和right里的offset是负数呢? 因为这里计算的是绝对的数值 计算的bottom需要小鱼sv的底部高度 所以要-10 同理用于right

    例3 让两个高度为150的view垂直居中且等宽且等间隔排列 间隔为10(自动计算其宽度)
    int padding1 = 10;
    [sv2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.mas_equalTo(sv.mas_centerY);
        make.left.equalTo(sv.mas_left).with.offset(padding1);
        make.right.equalTo(sv3.mas_left).with.offset(-padding1);
        make.height.mas_equalTo(@150);
        make.width.equalTo(sv3);
    }];
    [sv3 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.mas_equalTo(sv.mas_centerY);
        make.left.equalTo(sv2.mas_right).with.offset(padding1);
        make.right.equalTo(sv.mas_right).with.offset(-padding1);
        make.height.mas_equalTo(@150);
        make.width.equalTo(sv2);
    }];
    
    例3

    这里我们在两个子view之间互相设置的约束 可以看到他们的宽度在约束下自动的被计算出来了

    例4 在UIScrollView顺序排列一些view并自动计算contentSize
    UIScrollView *scrollView = [UIScrollView new];
        scrollView.backgroundColor = [UIColor whiteColor];
        [sv addSubview:scrollView];
        [scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(sv).with.insets(UIEdgeInsetsMake(5,5,5,5));
    }];
    UIView *container = [UIView new];
    [scrollView addSubview:container];
    [container 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 *subv = [UIView new];
        [container addSubview:subv];
        subv.backgroundColor = [UIColor colorWithHue:( arc4random() % 256 / 256.0 )
                                      saturation:( arc4random() % 128 / 256.0 ) + 0.5
                                      brightness:( arc4random() % 128 / 256.0 ) + 0.5
                                           alpha:1];
     
        [subv mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.and.right.equalTo(container);
        make.height.mas_equalTo(@(20*i));
         
            if ( lastView )
            {
                make.top.mas_equalTo(lastView.mas_bottom);
            }
            else
            {
                make.top.mas_equalTo(container.mas_top);
            }
        }];
     
        lastView = subv;
    }
    [container mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(lastView.mas_bottom);
    }];
    
    例4-1
    例4-2

    从scrollView的scrollIndicator可以看出 scrollView的内部已如我们所想排列好了
    这里的关键就在于container这个view起到了一个中间层的作用 能够自动的计算uiscrollView的contentSize

    未完待续

    相关文章

      网友评论

        本文标题:Masonry简单使用

        本文链接:https://www.haomeiwen.com/subject/liofrttx.html