Masonry - 自动布局

作者: 居然是村长 | 来源:发表于2016-03-12 10:25 被阅读2566次

    第三方库地址:https://github.com/SnapKit/Masonry
    pod 'Masonry'

    (UIKit - 中有系统的自动布局)

    一般的布局

        self.letfView = [UIView new];
        self.letfView.backgroundColor = [UIColor redColor];
        self.rightView = [UIView new];
        self.rightView.backgroundColor = [UIColor greenColor];
        
        [self.view addSubview:self.letfView];
        [self.view addSubview:self.rightView];
    
        [self.letfView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(self.view).mas_offset(10);// leftView 左边 = self.view 左边 +10
            make.top.mas_equalTo(self.view).mas_offset(20);// leftView 上边 = self.view 上边 +20
            make.height.mas_equalTo(100);// leftView 高 = 100
        }];
        
        [self.rightView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.letfView);// rightView 上边 = leftView 上边(即上边对齐)
            make.right.mas_equalTo(self.view).mas_offset(-10);// rightView 右边 = self.view 右边 - 10
            make.left.mas_equalTo(self.letfView.mas_right).mas_offset(20);// rightView 左边 = leftView 右边 + 20
            make.width.mas_equalTo(self.letfView);// rightView 宽 = leftView 宽
            make.height.mas_equalTo(self.letfView);// rightView 高 = leftView 高
        }];
       
    // 实现了最基础的 左右2个View 等高等宽等简单约束,在横竖屏切换通用。
    

    到这里,基本上已经可以开始玩masonry了,看完更多属性,基本小学毕业了。

    更多 make.XXX ,先手比较属性。

    left; 左
    top; 上
    right; 右
    bottom; 下
    leading; 左
    trailing; 右
    width; 宽
    height; 高
    centerX; x轴中心
    centerY; y轴中心
    baseline; 基线,没怎么用过
    
    leftMargin; 左边默认边距好像是20,下面的类似
    rightMargin;
    topMargin;
    bottomMargin;
    leadingMargin;
    trailingMargin;
    centerXWithinMargins;
    centerYWithinMargins;
    
    ----------- 分割线 ----------
    
    edges;4周
    size;大小
    center;中心
    对应语法略有不同,偏移方法也相对复杂一些。不偏移的话使用可以与上面一致。
    

    更多mas_equalTo(XXX) ,后手比较属性

    上半部分 基本雷同,如果不添加,就是默认与前面make.XXX 对应的mas_
    mas_left;
    mas_top;
    mas_right;
    mas_bottom;
    mas_leading;
    mas_trailing;
    mas_width;
    mas_height;
    mas_centerX;
    mas_centerY;
    mas_baseline;
    
    mas_leftMargin;
    mas_rightMargin;
    mas_topMargin;
    mas_bottomMargin;
    mas_leadingMargin;
    mas_trailingMargin;
    mas_centerXWithinMargins;
    mas_centerYWithinMargins;
    
    ----------- 分割线 ----------
    
    自动根据bar 高度设置的引导属性值,举个例子:
    存在navigationBar 时,mas_topLayoutGuideBottom 相当于 增加了44。
    不存在navigationBar 时,mas_topLayoutGuideBottom 相对于 0 。
    
    mas_topLayoutGuide;// navgationBar 相关,
    mas_topLayoutGuideTop;
    mas_topLayoutGuideBottom;
    
    mas_bottomLayoutGuide;// tabbar toolbar 相关
    mas_bottomLayoutGuideTop;
    mas_bottomLayoutGuideBottom;
    

    多条件布局

    • 大于、小于、等于
    mas_equalTo; =
    mas_greaterThanOrEqualTo; >=
    mas_lessThanOrEqualTo; <=
    // 大小于,使用场景感觉比较少。
    
    • 约束优先级
    简单举例:原本2个View是上下排布,当topView 移除时,bottomView,就使用次级约束而上移。
    
        [self.topView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.and.right.and.left.mas_equalTo(self.view);
            make.height.mas_equalTo(100);
        }];
        
        [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.topView.mas_bottom).priority(999);// 可以自己写优先值,越大越优先(1000 是xib 默认值,也是系统默认最大值)
            make.top.mas_equalTo(self.view).priorityLow();// 也可以用系统默认的优先值,low 代表250
            
            make.left.and.right.mas_equalTo(self.view);
            make.height.mas_equalTo(100);
        }];
    
    • 同时多个属性一致简写
    // 使用 and 链接属性
    make.left.and.top.and.width.and.height.mas_equalTo(self.letfView);
    
    • 同时与多个View存在关系,混合写
    // 数组形式    make.top.mas_equalTo(@[self.letfView.mas_top,self.rightView.mas_top]);
    
    • mas_equalTo(XXX) 的 mas_width 与 width 比较
    // mas_ 前缀的 是宏定义,封装好了直接可以使用 NSInteger,
    // 而没有前缀的 需要使用 NSNumber
            make.width.mas_equalTo(100);
            make.width.equalTo(@100);
    
    • mas_offset 与 with.offset 相比较
    
        UIEdgeInsets edg = UIEdgeInsetsMake(10, 20, 30, 40);
        
        [self.letfView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.mas_equalTo(self.view).mas_offset(edg);
            make.edges.mas_equalTo(self.view).with.insets(edg);
    
        }];
        
    // 使用 with. 需要区分 offset、insets、sizeOffset、centerOffset,分别使用偏移。
    // 使用mas_offset 自动区分了上面的几种情况,自动匹配了
    
    关于 偏移 可以继续研究CoreGraphice 框架中的 CGGeometry,下次在写。
           
    

    更新 重置约束 - 可以实现动画效果

    设置约束三大方法

    mas_makeConstraints 添加某个
    mas_updateConstraints 更新某个
    mas_remakeConstraints 重置全部
    
    • 简单更新约束
        // 原本 约束
        [self.letfView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.and.right.and.left.mas_equalTo(self.view);
            make.height.mas_equalTo(100);
        }];
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        // 更新约束
        [self.letfView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.view).mas_offset(300);
        }];
    
    • 结合平移动画
        // 修改 上面的 更新约束的方法,
        [self.letfView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.view).mas_offset(300);
        }];
        
        [self.letfView setNeedsLayout]; // 标记需要更新约束
        [UIView animateWithDuration:1. animations:^{
            [self.letfView layoutIfNeeded]; // 动画过程中更新约束,达到偏移效果
        }];
    

    布局涉及的其他属性 - 内容抗压缩,内容紧凑

    (我的理解,叫法可能不一样)

    举个例子:同水平方向有2 个 Label,内容都不确定有多少,即宽度不定。

    • 对2个Label 进行不定宽的布局,如果仅仅这样布局,对内容的控制,可能不是我们想要的。但是好像没有报错。可能默认处理了。(我这里尝试与第一个label 抗压缩,第二个label 内容优先紧凑,效果一致。)
        
        [self.leftLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.and.left.mas_equalTo(self.view);
        }];
        
        [self.rightLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.and.right.mas_equalTo(self.view);
            make.left.mas_equalTo(self.leftLabel.mas_right);
        }];
    
    • 对Label 添加属性
    (个人觉得第一步是这个:先显示内容)
        // 内容紧凑 - 优先完全显示内容,且不多占像素。
        [self.leftLabel setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
        [self.rightLabel setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
        
        
    
    // (个人觉得第二步是这个:调整内容是否压缩)
        // 抵抗 压缩,抗压缩低的,在上一步的基础上,进行压缩调整。
        [self.leftLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
        [self.rightLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal];
    
    

    1

    相关文章

      网友评论

      • swordjooy:Block里面 应该使用 weakSelf。
        ivanStronger:@说了是村长 只有造成了retain circle才需要用weak self,而不是block
        居然是村长:@swordjoy 恩,大部分block 都要weakSelf,但是在这里不会出现问题。。关于 block的 循环引用问题。我也再研究研究。你确定这里不用weak 会出问题吗?还请指教。

      本文标题:Masonry - 自动布局

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