不得不说,自从接触了Masonry的链式编程,这样的写法,萦绕在脑海中,久久无法散去,一得机会便要时不时的展现一把.
写项目的时候,每次设置空间的属性值的时候,要写很多控件的方法,我尝试过去提取一些常用的方法,来通过传递一些值来设置控件的属性,比如:
//声明
- (void)nj_buttonWithNormalTitle:(NSString *)normalTitle highlightedTitle:(NSString *)highlightedTitle normalImage:(UIImage *)normalImage highlightedImage:(UIImage *)image{
}
//调用
[self nj_buttonWithNormalTitle:@"a"
highlightedTitle:@"b"
normalImage:[UIImage imageNamed:@"1"]
highlightedImage:[UIImage imageNamed:@"2"]];
上述方法,声明了一个带有一大堆参数的方法,调用时也是一大堆,而且灵活性不大,一个按钮那么多的属性,我想到了链式语法. 好处是一个对象可以通过点语法来设置一大堆的属性,而且这些属性的先后顺序随意.不方便的是参数没有类型提示,队友看起来或者使用起来还需要跳到方法声明去看看怎么用.
链式语法还是比较简单的,网上有很多教程,我就不重点讲述了,我这里贴一个比较简单的吧.
//声明
- (UIButton *(^)(NSString *title, UIControlState state))nj_buttonTitle;
//实现
//返回一个UIButton类型的block,
- (UIButton *(^)(NSString *title, UIControlState state))njTitle;
{
return ^UIButton *(NSString *title, UIControlState state) {
[self setTitle:title forState:state];
return self;
};
}
//调用:
b.njTitle(@"hello", UIControlStateNormal);
//因为b.njTitle会得到返回值,返回值是一个block,block的调用就是直接在block后面使用 (),因为我们njTitle返回的block是需要传值的,所以直接在 () 里面写上值,第一个是title,第二个是按钮的状态.
//因为block是一个UIButton类型,所以可以继续通过点语法来调用别的按钮的方法
//这个方法声明我写在了一个UIButton的分类当中.
我简单的设置一个按钮的值的时候,就像下面这样:
///没有用链式语法
[b setTitle:@"hello" forState:UIControlStateNormal];
[b setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[b setBackgroundColor:[UIColor redColor]];
[b addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];
///使用了链式语法
b
.njTitle(@"hello", UIControlStateNormal)
.njTitleColor([UIColor blackColor], UIControlStateNormal)
.njAddAction(self, @selector(btnAction), UIControlEventTouchUpInside)
.njBackgroundColor([UIColor redColor]);
嗯..看起来好像没什么卵用.但重点是和大多数人的写法不一样,这就是目的- -.. 接下来我们看BoxValue. 这个还是有点意思的. 我之所以会看到这个,是因为我搞错了,我以为分类中的block参数是不能放非对象类型的参数,顿时想到masonry的value装箱,后来发现,原来像CGFloat,float这样的数据类型是可以作为参数的- -..阴差阳错的看了一波boxValue.
首先我们在设置约束的时候肯定会这样写:
make.top.left.mas_equalTo(_contentRoundView).mas_offset(5);
我们按住command键,然后点mas_offset,就可以跳到MASConstraint.h文件的243行,有如下定义:
#define mas_offset(...) valueOffset(MASBoxValue((__VA_ARGS__)))
接着,我们继续点MASBoxValue,会跳到MASUtilities文件的底部,有如下定义:
#define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value))