美文网首页
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