Masonry常用使用方式
UIView *yellowV = [[UIView alloc] init];
[yellowV setBackgroundColor:[UIColor yellowColor]];
[self.view addSubview:yellowV];
[yellowV mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.right.bottom.equalTo(self.view).with.mas_offset(20);
}];
需要注意的几个问题:
- 添加Masonry布局约束的控件不用设置frame;
- 一定要在添加布局之前添加子控件到父控件;
- 所有布局问题交给make这个布局管理者执行;
我们仔细观察这一长串代码,在传统Objective-C中我们使用方法都是采用’[]'这种方式,对于setter和getter方法我们采用点语法来使用,但是还有见到能够点一串的,实际上,这个就是我们今天介绍的链式反应编程思想。
make.left.top.right.bottom.equalTo(self.view).with.mas_offset(20);
Masonry就是一个链式编程思想的例子
思考:一般什么情况下可以使用点语法?
通常,类似于UIView声明一个view后,view就可以调用里面的setter和getter方法,一般使用setter和getter方法需要声明成员属性。
如下,就是UIView中定义常用的成员属性,它们对应着各自的setter和getter方法,因此可以使用点语法。
@property(nonatomic) BOOL clipsToBounds;
@property(nullable, nonatomic,copy) UIColor *backgroundColor UI_APPEARANCE_SELECTOR;
@property(nonatomic) CGFloat alpha;
@property(nonatomic,getter=isOpaque) BOOL opaque;
@property(nonatomic) BOOL clearsContextBeforeDrawing;
@property(nonatomic,getter=isHidden) BOOL hidden;
@property(nonatomic) UIViewContentMode contentMode;
但是,我们介绍的链式编程思想是由Block实现的,如果使用这种编程方式着实搬不上台面,Block很多初次学习的人都会诚惶诚恐,不过,Block的好处真的是无可比拟的。
Block基本思想
首先,我们来看一个Block模型。
- (NSString *(^)(void))block;
这是一个最简单的block的声明了,我们来解读一下
- 返回值: NSString;
- 传入的参数: void;
- Block的名称:block;
我们在方法中声明完block通常怎么调用呢?
很简单,写出它的名称加一对圆括号就可以调用block内容,可以这样理解block,就是将要执行的代码封装到了一个类似于C语言中的函数中,当需要调用时候,使用函数名称直接调用就可以了。
block();
链式编程思想
我们既然可以使用Block名称调用Block,同时,对外,block也可以用做实力化对象,我们不如构造一个不断返回自身的Block出来,不断让自身的类调用自己的Block然后返回自身对象,说起来,肯定有些绕口,看看代码就知道了。
假设我们的类是BlockTest
+ (BlockTest *(^)(void))block1;
- (BlockTest *(^)(void))block2;
- (BlockTest *(^)(void))block3;
- (BlockTest *(^)(void))block4;
- (BlockTest *(^)(void))block5;
- (BlockTest *(^)(void))block6;
这样对外调用效果就如下:
+ (BlockTest * _Nonnull (^)(void))block1{
__weak typeof(self) weakSelf = self;
return ^BlockTest*(){
__strong typeof(weakSelf) self = weakSelf;
return [[self alloc] init];
};
}
- (BlockTest * _Nonnull (^)(void))block2{
__weak typeof(self) weakSelf = self;
return ^BlockTest*(){
__strong typeof(weakSelf) self = weakSelf;
return self;
};
}
- (BlockTest * _Nonnull (^)(void))block3{
__weak typeof(self) weakSelf = self;
return ^BlockTest*(){
__strong typeof(weakSelf) self = weakSelf;
return self;
};
}
- (BlockTest * _Nonnull (^)(void))block4{
__weak typeof(self) weakSelf = self;
return ^BlockTest*(){
__strong typeof(weakSelf) self = weakSelf;
return self;
};
}
- (BlockTest * _Nonnull (^)(void))block5{
__weak typeof(self) weakSelf = self;
return ^BlockTest*(){
__strong typeof(weakSelf) self = weakSelf;
return self;
};
}
- (BlockTest * _Nonnull (^)(void))block6{
__weak typeof(self) weakSelf = self;
return ^BlockTest*(){
__strong typeof(weakSelf) self = weakSelf;
return self;
};
}
这样我们就可以利用链式进行操作了。
BlockTest.block1().block2().block3().block4().block5().block6();
带参数的Block链式操作
我们改写了block6,传入一个字符串参数。
+ (BlockTest *(^)(void))block1;
- (BlockTest *(^)(void))block2;
- (BlockTest *(^)(void))block3;
- (BlockTest *(^)(void))block4;
- (BlockTest *(^)(void))block5;
- (BlockTest *(^)(NSString *))block6;
其余不变,唯独block6中我们输出要传入的内容。
- (BlockTest * _Nonnull (^)(NSString * _Nonnull))block6{
__weak typeof(self) weakSelf = self;
return ^BlockTest*(NSString *context){
__strong typeof(weakSelf) self = weakSelf;
NSLog(@"%@",context);
return self;
};
}
BlockTest.block1().block2().block3().block4().block5().block6(@"I am block6...");
2020-04-26 09:17:33.646799+0800 ReadMasonry[2424:210096] I am block6…
以上就是Block作为链式编程的常用使用方法,对于其核心思想,我们后面几片会通过Masonry框架详细的了解链式编程思想的优点和使用方法。