iOS 第三方框架-Masonry

介绍地址:http://www.cocoachina.com/ios/20141219/10702.html

官网:https://github.com/SnapKit/Masonry

记住:一定要先添加View , 再设置位置

NSLayout 相关枚举

typedef NS_ENUM(NSInteger, NSLayoutRelation) {
    NSLayoutRelationLessThanOrEqual = -1,          //小于等于
    NSLayoutRelationEqual = 0,                     //等于
    NSLayoutRelationGreaterThanOrEqual = 1,        //大于等于
};
typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
    NSLayoutAttributeLeft = 1,                     //左侧
    NSLayoutAttributeRight,                        //右侧
    NSLayoutAttributeTop,                          //上方
    NSLayoutAttributeBottom,                       //下方
    NSLayoutAttributeLeading,                      //首部
    NSLayoutAttributeTrailing,                     //尾部
    NSLayoutAttributeWidth,                        //宽度
    NSLayoutAttributeHeight,                       //高度
    NSLayoutAttributeCenterX,                      //X轴中心
    NSLayoutAttributeCenterY,                      //Y轴中心
    NSLayoutAttributeBaseline,                     //文本底标线
                                                                                                                                                    
    NSLayoutAttributeNotAnAttribute = 0            //没有属性
};

左右顶部宽高一样:

make.left.right.and.top.equalTo(self);

实际使用

/**
 *  底部购买栏 初始化
 */
- (void)setupFooterView
{
    CGFloat footerViewH = 50;
    
    // 背景栏
    UIView *footerView = [[UIView alloc] init];
    footerView.backgroundColor = [UIColor whiteColor];
    footerView.layer.borderColor = [UIColor colorWithHexString:Color_Line].CGColor;
    footerView.layer.borderWidth = 0.3;
    [self.view addSubview:footerView];

    // 首页
    UIButton *homeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    homeBtn.titleLabel.font = [UIFont systemFontOfSize:12];
    homeBtn.layer.borderWidth = 0.3;
    homeBtn.layer.borderColor = [UIColor colorWithHexString:Color_Line].CGColor;
    [homeBtn setTitle:@"首页" forState:UIControlStateNormal];
    [homeBtn setTitleColor:[UIColor colorWithHexString:@"6c6c6c"] forState:UIControlStateNormal];
    [homeBtn setImage:[UIImage imageNamed:@"home"] forState:UIControlStateNormal];
    [homeBtn setImageEdgeInsets:UIEdgeInsetsMake(-14, 12.5, 0, 0)];
    [homeBtn setTitleEdgeInsets:UIEdgeInsetsMake(18, -22, 0, 0)];
    [homeBtn addTarget:self action:@selector(homeClick) forControlEvents:UIControlEventTouchUpInside];
    [footerView addSubview:homeBtn];
    
    // 加入购物车
    UIButton *addCartBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    addCartBtn.backgroundColor = [UIColor colorWithHexString:@"fc714b"];
    addCartBtn.titleLabel.font = [UIFont systemFontOfSize:16];
    [addCartBtn setTitle:@"加入购物车" forState:UIControlStateNormal];
    [addCartBtn setTitleColor:[UIColor colorWithHexString:@"ffffff"] forState:UIControlStateNormal];
    [addCartBtn setBackgroundImage:[Tool createImageWithColor:[UIColor colorWithHexString:Color_Line]] forState:UIControlStateSelected];
    [addCartBtn addTarget:self action:@selector(buyClick:) forControlEvents:UIControlEventTouchUpInside];
    [footerView addSubview:addCartBtn];
    if (![self.goodsDetail.goods.only_one_step_buy isEqualToString:@"0"]) {
        addCartBtn.selected = YES;
        addCartBtn.userInteractionEnabled = NO;
    }
    
    // 立即购买
    UIButton *buyBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    buyBtn.backgroundColor = [UIColor colorWithHexString:Color_Red];
    buyBtn.titleLabel.font = [UIFont systemFontOfSize:16];
    [buyBtn setTitle:@"立即购买" forState:UIControlStateNormal];
    [buyBtn setTitleColor:[UIColor colorWithHexString:@"ffffff"] forState:UIControlStateNormal];
    [buyBtn setBackgroundImage:[Tool createImageWithColor:[UIColor colorWithHexString:@"e8e8e8"]] forState:UIControlStateSelected];
    [buyBtn addTarget:self action:@selector(buyClick:) forControlEvents:UIControlEventTouchUpInside];
    [footerView addSubview:buyBtn];
    
    // 库存为0,底部按钮变灰
    if ([self.goodsDetail.goods.goods_number intValue] <= 0) {
        buyBtn.selected = YES;
        buyBtn.userInteractionEnabled = NO;
        
        addCartBtn.selected = YES;
        addCartBtn.userInteractionEnabled = NO;
    }
    
    [footerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(CGSizeMake(ScreenWidth,footerViewH));
        make.bottom.mas_equalTo(@0);
    }];
    
    [homeBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(footerView.mas_top);
        make.left.equalTo(footerView.mas_left);
        make.bottom.equalTo(footerView.mas_bottom);
        make.width.equalTo(@54);
        make.height.equalTo(footerView.mas_height);
    }];

    [addCartBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(footerView.mas_top);
        make.left.equalTo(homeBtn.mas_right);
        make.bottom.equalTo(footerView.mas_bottom);
        make.right.equalTo(buyBtn.mas_left);
        
        make.width.equalTo(@[addCartBtn,buyBtn]);
        make.height.equalTo(footerView.mas_height);
    }];
    
    [buyBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(footerView.mas_top);
        make.left.equalTo(addCartBtn.mas_right);
        make.bottom.equalTo(footerView.mas_bottom);
        make.right.equalTo(footerView.mas_right);
        
        make.width.equalTo(@[addCartBtn,buyBtn]);
        make.height.equalTo(footerView.mas_height);
    }];

    _footerView = footerView;
}

效果:

两个元素相对居中

效果红色框如:

具体代码:

    UIView *couponView = [[UIView alloc] init];
    couponView.backgroundColor = [UIColor redColor];
    [payInfoView addSubview:couponView]; //父控件 加入 容器
    [couponView mas_makeConstraints:^(MASConstraintMaker *make) {
       //make.height.top.centerX.equalTo(couponView.superview);//width不设置,让其根据子控件宽度进行适配
        make.centerX.equalTo(payInfoView);
        make.height.mas_equalTo(payInfoViewFooterH);
        make.bottom.mas_equalTo(payInfoView.mas_bottom);
    }];
    
    // 已优惠
    UILabel *couponLabel = [[UILabel alloc] init];
    couponLabel.textColor = VSColorFromRGB(0x585c64);
    couponLabel.font = [UIFont systemFontOfSize:12];
    [couponView addSubview:couponLabel];
    couponLabel.text = [NSString stringWithFormat:@"已优惠¥%@",@"123"];
    
    // 点击详情
    UIButton *couponLookDescButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [couponLookDescButton setImage:[UIImage imageNamed:@"pay_instalment_explain"] forState:UIControlStateNormal];
    [couponView addSubview:couponLookDescButton];
    
    [couponLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(couponView);
        make.centerY.equalTo(couponView);
        make.right.equalTo(couponLookDescButton.mas_left).offset(-5);
    }];
    
    [couponLookDescButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(couponLabel.mas_right).offset(5);
        make.centerY.equalTo(couponView);
        make.right.equalTo(couponView);
    }];

计算自动约束高度

    // 最终总高度
    [_payPeriodBgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self);
        make.left.right.equalTo(self);
        make.bottom.equalTo(_periodDetailListView.mas_bottom);
    }];
    
    // 更新约束
    [self layoutIfNeeded];
    
    // 视图的最大 Y 值
    CGFloat h= CGRectGetMaxY(_payPeriodBgImageView.frame);

mas_makeConstraints &&  mas_remakeConstraints && mas_updateConstraints 用法与注意事项

1 mas_makeConstraints 只负责新增约束,Autolayout 不能同时存在两条针对于同一对象约束 否则会报错 
注意:在添加约束之前一定要添加到view( [testView addSubview:self.view])上 否则会报错

[testView mas_makeConstraints:^(MASConstraintMaker *make) { 
make.leading.equalTo(view1.mas_trailing).offset(10); 
make.bottom.equalTo(view2.mas_bottom).offset(-2); 
make.height.mas_equalTo(70); 
make.width.mas_equalTo(50); 
}];

2 mas_remakeConstraints 会清除之前的所有约束 仅保留最新的约束

如下:会清除原来的以view1 和view2 为参照的约束 保留 以view3 和view4 为参照的约束 
[testView mas_remakeConstraints :^(MASConstraintMaker *make) { 
make.bottom.equalTo(view3.mas_top).offset(-10); 
make.centerX.equalTo(view4.mas_centerX); 
make.height.mas_equalTo(70); 
make.width.mas_equalTo(50); 
}];

3 mas_updateConstraints 针对上面的情况 会更新block中出现的约束 不会导致出现两个相同的约束的情况

注意: 同一个对象 使用mas_updateConstraints 一定要保证 block中要更新的元素是 其使用mas_makeConstraints 设置的约束

如下就是正确的 则不会出现约束冲突问题 
[testView mas_updateConstraints:^(MASConstraintMaker *make) { 
make.bottom.equalTo(view1.mas_top).offset(-60); 
必须是 同一参照对象(都是以view1)同一参照属性(都是以view1的mas_top) 
}];

但是下面的就不对了 就会出现约束冲突 在iOS 7 及其以下会出现由于约束冲突出现的崩溃

[testView mas_updateConstraints:^(MASConstraintMaker *make) { 
make.bottom.equalTo(view2.mas_top).offset(-10); 
make.centerX.equalTo(view4.mas_centerX); 
原因1:不同一参照对象 (原来是view1 现在是view2) 
原因2 testView 在 mas_makeConstraints中没有设置 center 所以无法更新 
}];

解决办法:使用mas_remakeConstraints 清除原来的约束 重新设置约束; 
}];

其它可参考:http://www.jianshu.com/p/2b57ece2b3b8

原文地址:https://www.cnblogs.com/jys509/p/4911602.html