美文网首页
AutoLayout之Masonry

AutoLayout之Masonry

作者: 黄定师 | 来源:发表于2019-05-12 18:08 被阅读0次

    什么是Masonry

    Masonry是一个对原生NSLayoutConstraint布局进行封装的第三方自动布局框架,采用链式编程法给开发者提供接口。相比系统原生自动布局来说,Masonry的布局功能是有过之而无不及。

    另外Masonry是同时支持Mac和iOS平台的,在这两个平台上都可以使用Masonry进行自动布局。


    Masonry布局初体验

    在介绍NSLayoutConstraint布局时,有个示例是布局一个简单的View(top:50,left:50,width:150,height:150)。现在改用Masonry实现之。

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = [UIColor whiteColor];
        
        UIView *layoutView = [[UIView alloc]init];
        // Masonry内部会主动添上这句,所以这里不用加
        // layoutView.translatesAutoresizingMaskIntoConstraints = NO;
        layoutView.backgroundColor = [UIColor purpleColor];
        [self.view addSubview:layoutView];
        
        [layoutView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_offset(50.0);
            make.left.mas_offset(50.0);
            make.height.mas_equalTo(150.0);
            make.width.mas_equalTo(150.0);
        }];
    
    //    // top和left以及width和heigth相同,可以进一步简写
    //    [layoutView mas_makeConstraints:^(MASConstraintMaker *make) {
    //        make.top.left.mas_offset(50.0);
    //        make.height.width.mas_equalTo(150.0);
    //    }];
    }
    

    Masonry采取链式编程的方式,让代码非常清晰易懂,而且代码量非常少。之前用原生方式写很多代码才能实现的布局,用Masonry几行代码就可以搞定。


    Masonry布局示例

    这里我不打算讲Masonry 的框架实现方式,因为有很多大佬已经分析的很清楚,并且这些资料也很容易获取。建议没有看过源码的,尽量去看下,搞懂链式编程法对自己的提升还是很大的。这里我想用Masonry实现左右两个Label宽高不固定的布局。

    布局需求:

    1. 横向:leftLabel的宽度由其内容确定(内容不会超出屏幕宽度);rightLabel的左边距离leftLabel的右边为10。
    2. 纵向:两个label均居中,且高度相同;rightLabel可能会有多行。
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = [UIColor lightGrayColor];;
        
        UILabel *leftLabel = [[UILabel alloc]init];
        leftLabel.numberOfLines = 1;
        leftLabel.backgroundColor = [UIColor purpleColor];
        // 设置抗拉伸级,即label不可被拉伸
        [leftLabel setContentHuggingPriority:(UILayoutPriorityRequired) forAxis:(UILayoutConstraintAxisHorizontal)];
        // 设置抗压缩级,即label不可被压缩
        [leftLabel setContentCompressionResistancePriority:(UILayoutPriorityRequired) forAxis:(UILayoutConstraintAxisHorizontal)];
        
        UILabel *rightLabel = [[UILabel alloc]init];
        rightLabel.numberOfLines = 0;
        rightLabel.backgroundColor = [UIColor magentaColor];
        
        [self.view addSubview:leftLabel];
        [self.view addSubview:rightLabel];
        
        leftLabel.text = @"名剑无名倦收天";
        rightLabel.text  = @"江天一色无纤尘,鱼龙潜跃观道身。天人焉有两般义,道不虚行只在人。";
        
        [leftLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.mas_offset(0);
            make.left.mas_offset(0);
            make.height.equalTo(rightLabel);
        }];
        
        [rightLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(leftLabel);
            make.left.equalTo(leftLabel.mas_right).mas_offset(10.0);
            make.right.mas_offset(0);
        }];
    }
    

    布局效果见下图:


    image.png

    说明

    Apple在iOS11提出了布局安全域的概念,Masonry也同步进行了适配。特别是碰到刘海屏的时候,要加以考虑。

    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        if (@available(iOS 11.0,*)) {
            make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
            make.left.equalTo(self.view.mas_safeAreaLayoutGuideLeft);
            make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
            make.right.equalTo(self.view.mas_safeAreaLayoutGuideRight);
        } else {
            make.edges.mas_offset(0);
        }
    }];
    

    如果考虑导航栏以及选项卡控制器,最好写成下面这样:

    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        if (@available(iOS 11.0,*)) {
            make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
            make.left.equalTo(self.view.mas_safeAreaLayoutGuideLeft);
            make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
            make.right.equalTo(self.view.mas_safeAreaLayoutGuideRight);
        } else {
            make.top.equalTo(self.mas_topLayoutGuide);
            make.bottom.equalTo(self.mas_bottomLayoutGuide);
            make.left.right.mas_offset(0);
        }
    }];
    

    相关文章

      网友评论

          本文标题:AutoLayout之Masonry

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