OC----Masonry 自动布局

Masonry 中的坑
1. 在使用Masonry添加约束之前,需要在addSubview之后才能使用,否则会导致崩溃。
2. 在添加约束时初学者经常会出现一些错误,约束出现问题的原因一般就是两种:约束冲突和缺少约束。对于这两种问题,可以通过调试和log排查。
3. 之前使用Interface Builder添加约束,如果约束有错误直接就可以看出来,并且会以红色或者黄色警告体现出来。而Masonry则不会直观的体现出来,而是以运行过程中崩溃或者打印异常log体现,所以这也是手写代码进行AutoLayout的一个缺点。

一、Masonry 基础 API

mas_makeConstraints()    添加约束
mas_remakeConstraints()  移除之前的约束,重新添加新的约束
mas_updateConstraints()  更新约束

equalTo()       参数是对象类型,一般是视图对象或者 mas_width 这样的坐标系对象
mas_equalTo()   和上面功能相同,参数可以传递基础数据类型对象,可以理解为比上面的 API 更强大

width()         用来表示宽度,例如代表 view 的宽度
mas_width()     用来获取宽度的值。和上面的区别在于,一个代表某个坐标系对象,一个用来获取坐标系对象的值

二、equalTo或者width这样的,有时候需要涉及到使用mas_前缀,这在开发中需要注意作区分。
如果在当前类引入#import “Masonry.h”之前,用下面两种宏定义声明一下,就不需要区分mas_前缀。

// 定义这个常量,就可以不用在开发过程中使用"mas_"前缀。
define MAS_SHORTHAND

// 定义这个常量,就可以让 Masonry 帮我们自动把基础数据类型的数据,自动装箱为对象类型。
define MAS_SHORTHAND_GLOBALS

三、添加了and和with两个方法。这两个方法内部实际上什么都没干,只是在内部将self直接返回,功能就是为了更加方便阅读,对代码执行没有实际作用
make.top.and.bottom.equalTo(self.containerView).with.offset(padding);

内部代码实现,实际上就是直接将self返回

- (MASConstraint *)with {
    return self;
}

四、更新约束(4个)和布局(3个)

- (void)updateConstraintsIfNeeded  调用此方法,如果有标记为需要重新布局的约束,则立即进行重新布局,内部会调用 updateConstraints 方法
- (void)updateConstraints          重写此方法,内部实现自定义布局过程
- (BOOL)needsUpdateConstraints     当前是否需要重新布局,内部会判断当前有没有被标记的约束
- (void)setNeedsUpdateConstraints  标记需要进行重新布局

- (void)setNeedsLayout  标记为需要重新布局
- (void)layoutIfNeeded  查看当前视图是否被标记需要重新布局,有则在内部调用 layoutSubviews 方法进行重新布局
- (void)layoutSubviews  重写当前方法,在内部完成重新布局操作

五、Masonry 本质上就是对系统 AutoLayout 进行的封装,包括里面很多的 API,都是对系统 API 进行了一次二次包装

typedef NS_OPTIONS(NSInteger, MASAttribute) {
    MASAttributeLeft = 1 << NSLayoutAttributeLeft,
    MASAttributeRight = 1 << NSLayoutAttributeRight,
    MASAttributeTop = 1 << NSLayoutAttributeTop,
    MASAttributeBottom = 1 << NSLayoutAttributeBottom,
    MASAttributeLeading = 1 << NSLayoutAttributeLeading,
    MASAttributeTrailing = 1 << NSLayoutAttributeTrailing,
    MASAttributeWidth = 1 << NSLayoutAttributeWidth,
    MASAttributeHeight = 1 << NSLayoutAttributeHeight,
    MASAttributeCenterX = 1 << NSLayoutAttributeCenterX,
    MASAttributeCenterY = 1 << NSLayoutAttributeCenterY,
    MASAttributeBaseline = 1 << NSLayoutAttributeBaseline,
};

一、设置内边距

/** 
 设置 yellow 视图和 self.view 等大,并且有 10 的内边距。
 注意根据 UIView 的坐标系,下面 right 和 bottom 进行了取反。所以不能写成下面这样,否则 right、bottom 这两个方向会出现问题。
 make.edges.equalTo(self.view).with.offset(10);

 除了下面例子中的 offset()方法,还有针对不同坐标系的 centerOffset()、sizeOffset()、valueOffset()之类的方法。
 */
[self.yellowView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(self.view).with.offset(10);
    make.top.equalTo(self.view).with.offset(10);
    make.right.equalTo(self.view).with.offset(-10);
    make.bottom.equalTo(self.view).with.offset(-10);
}];

二、通过 insets 简化设置内边距的方式

//下面的方法和上面例子等价,区别在于使用 insets()方法。
[self.blueView mas_makeConstraints:^(MASConstraintMaker *make) {
    // 下、右不需要写负号,insets 方法中已经为我们做了取反的操作了。
    make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(10, 10, 10, 10));
}];

三、更新约束

// 设置 greenView 的 center 和 size,这样就可以达到简单进行约束的目的
[self.greenView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.center.equalTo(self.view);

    // 这里通过 mas_equalTo 给 size 设置了基础数据类型的参数,参数为 CGSize 的结构体
    make.size.mas_equalTo(CGSizeMake(300, 300));
}];

// 为了更清楚的看出约束变化的效果,在显示两秒后更新约束。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [self.greenView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view).offset(100);
        make.size.mas_equalTo(CGSizeMake(100, 100));
    }];
});
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值