iOS技术IOS

YKAutolayout --- Make Masonry Ea

2016-11-30  本文已影响204人  星___尘

项目Github地址

YKAutolayout

Masonry 的 使用

做过iOS的对Masonry这个库应该都会比较熟悉,其主要原理是对苹果原生的Autolayout进行了一套封装,提供更加易用的API给使用者使用。相对于苹果原生的Autolayout,Masonry引入的约束写法更具有可读性。

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
[view1 mas_makeConstraints:^(MASConstraintMaker *make) { 
     make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler 
     make.left.equalTo(superview.mas_left).with.offset(padding.left); 
     make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom); 
     make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];

部分约束能提供更简洁的写法

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
     make.edges.equalTo(superview).with.insets(padding);
}];

Masonry 的 缺点

尽管Masonry的写法相对苹果原生Autolayout来说是一个很大的进步,但是带来一些缺点,例如Masonry的使用给界面布局带来大量重复的胶水代码。
举个demo例子:
Masonry写法:

    [scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.bottom.mas_equalTo(0);
    }];
    [viewA mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(0);
        make.left.mas_equalTo(10);
        make.width.mas_equalTo(300);
        make.height.mas_equalTo(310);
    }];
    [viewB mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(viewA.mas_bottom).offset(50);
        make.left.mas_equalTo(10);
        make.width.mas_equalTo(300);
        make.height.mas_equalTo(300);
    }];
    [viewC mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(viewB.mas_bottom).offset(51);
        make.left.mas_equalTo(10);
        make.width.mas_equalTo(viewB).multipliedBy(0.5);
        make.height.mas_equalTo(viewC).multipliedBy(2.0);
    }];
    [btn1 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(viewC.mas_bottom).offset(12);
        make.width.mas_equalTo(100);
        make.height.mas_equalTo(50);
        make.centerX.mas_equalTo(scrollView);
    }];

可以看到,只是写了4个View的布局约束,就已经是30多行的代码。如果当一个界面有大量view的时候,可想而知会有多痛苦,保守估计会是:view的数量 * 6 行布局约束代码。从Masonry的代码可以看出,其存在大量重复的

mas_makeConstraints:^(MASConstraintMaker *make)
make
mas_equalTo

等描述性代码,使得整个约束设置变得臃肿,会把整个View变得Massive。

链式语法

Masonry中一个很重要的特点是链式语法,最显著的特点是xx.xx.xx的连续调用,例如
make.top.mas_equalTo(viewA.mas_bottom).offset(50);
看到这里,可能会想,能不能把Masonry用链式语法写的更简洁一点呢?

SDAutolayout的启发

SDAutolayout是一个新出的布局库,其最大特点是可以实现一行代码布局,其链式语法实现的非常优雅:

_view.sd_layout.leftSpaceToView(self.view,10).topSpaceToView(self.view,80).heightIs(130).widthRatioToView(self.view, 0.4);

哪究竟能不能像SDAutolayout一样,实现一行代码的Masonry布局呢?

新的选择 --- YKAutolayout

由于对Masonry的热爱和对Masonry胶水代码的厌恶,受SDAutolayout启发,本人选择封装Masonry的使用,自造一套模仿SDAutolayout的风格的布局工具YKAutolayout

针对上面Masonry写的demo例子,换成YKAutolayout的写法是这样的:

    scrollView.yk_make.top(0).left(0);
    scrollView.yk_make.right(0).bottom(0).done();

    viewA.yk_make.top(33).left(10).width(310).height(310).done();

    viewB.yk_make.topTo(viewA.mas_bottom,50).left(10).width(300).height(300).done();

    viewC.yk_make.topTo(viewB.mas_bottom,51).left(10).widthAspectTo(viewB,0.5).heightAspectTo(viewC.mas_width,2.0)
            .done();

    btn1.yk_make.topTo(viewC.mas_bottom,12).width(100).height(50).centerXTo(scrollView,0).done();

相比Masonry,大大减少了胶水代码,写起来更简洁,用法也与Masonry保持一致,还能跟Masonry混编(不建议)。对于熟悉Masonry的人来说,是可以尝试一下的。

当然,有个缺点是,YKAutolayout暂时还没加上优先级的设置,对于要使用优先级的约束,还是可以使用原生Masonry来做。

YKAutolayout有个很重要特点时能跟Maosnry混编,对于一些无法使用YKAutolayout暂时无法实现的高级特性(例如约束优先级),可以使用Masonry实现。

scrollView.yk_make.top(0).left(0);
scrollView.yk_make.right(0).bottom(0).done(); 
viewA.yk_make.top(33).left(10).width(310).height(310).done(); 
[viewB mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(viewA.mas_bottom).offset(50);
        make.left.mas_equalTo(10);
        make.width.mas_equalTo(300);
        make.height.mas_equalTo(300);
  }];
viewC.yk_make.topTo(viewB.mas_bottom,51).left(10).widthAspectTo(viewB,0.5).heightAspectTo(viewC.mas_width,2.0) .done();
 btn1.yk_make.topTo(viewC.mas_bottom,12).width(100).height(50).centerXTo(scrollView,0).done();

YKAutolayout 的原理

简单来说就是将top,left,width,height等属性缓存起来,在调用done函数时一次性将其放进Masonry中进行布局。而添加约束时抛弃Masonry的风格,使用SDAutolayout的风格,则能大大减少胶水代码的产生,对使用者更加友好。

Reference

Masonry
SDAutolayout
链式语法

上一篇 下一篇

猜你喜欢

热点阅读