您的位置:首页 > Web前端 > React

ReactiveCocoa那些干货——2

2016-04-06 15:43 363 查看
前言:

笔者在之前的某个项目中由于需求调用系统摄像机,于是在此条件下封装了一个RAC关于UIImagePickerController的一个Category,以RAC框架中对UIImagePickerController的Category封装为提前,对UIImagePickerController进行了二次封装。

UIImagePickerController+RACSignalSupport介绍
首先,让我们来看一下RACSignalSupport拓展中对UIImagePickerController所做的事情吧,如下:

通过RAC的源码可以看出来,在UIImagePickerController跟之前笔者提及的UIAlertView封装是类似的,同样是对委托进行拦截,原理这里就不多做说明,不清楚的童鞋可以回头看看之前的博文。

关于RAC对UIImagePickerController的这个Category,笔者早在2015年初的时候就使用过,但是使用之初就发现这个Category对imagePickerControllerDidCancel: 的拦截在某些情况下有些限制的,源码中,takeUntil:方法试图拦截imagePickerControllerDidCancel:的信号,思路上是正确的,但是某些情况下这个拦截会失灵,因此,笔者很干脆的将这个委托另外抽出了一个Category进行封装,这个Category是控制器(UIViewController的Category)。

并且实现如下:

- (RACSignal*)rac_willCancelSignalForImagePickerController:(UIImagePickerController*)imagePickerController {

if (![selfcheckImagePickerController:imagePickerController]){
return
nil;
}
return [RACSignalcreateSignal:^RACDisposable*(id<RACSubscriber>subscriber)
{

[[[imagePickerController.rac_delegateProxysignalForSelector:@selector(imagePickerControllerDidCancel:)]deliverOn:[RACSchedulermainThreadScheduler]]subscribeNext:^(idx)
{
[subscriber sendNext:x];
[subscriber sendCompleted];
}];
return
nil;
}];
}
思路是:通过统一截取Delegate的方法,截取imagePickerControllerDidCancel:这个回调的方法,并组建信号管道,将点击到Cancel的信号逐级传递。

在Category中先添加如下的Cancel信号处理
@weakify(self);
[[selfrac_willCancelSignalForImagePickerController:imagePickerController]subscribeNext:^(idx)
{
@strongify(self);
[selfcameraDeviceDismissViewControllerForAnimated:YEScompletion:dismissCompletion];
}];

然后在需要创建系统相册/摄像机的地方进行调用

[[[selfopenCameraDeviceForDeviceType:kSystemAnimationTypePhotowithCompletion:^(UIImagePickerController
*imagePickerController) {
@strongify(self);
[selfpresentViewController:imagePickerControlleranimated:YEScompletion:^{

}];
} dismissCompletion:^{
//这里是点击Cancel,dismiss控制器完成后调用的block

}] deliverOn:[RACSchedulermainThreadScheduler]]subscribeNext:^(NSDictionary*dic)
{
NSLog(@"dic: %@", dic);
UIImage*image = dic[@"UIImagePickerControllerEditedImage"];
NSLog(@"image: %@", image);
[selfcameraDeviceDismissViewControllerForAnimated:YEScompletion:^{

}];
}];

总结:
关于RAC对于UIKit的封装,笔者的理解是可以将它看成一个拼图,不管是基于RAC的封装Category进行的二次封装也好,或者直接使用RACDelegateProxy进行的封装也好,都是从源头上获取事件,将其包装为一个Signal,由开发者所组装的管道,进行的信号传递,最后修改变更视觉上的UI的过程,这也是RAC框架最为棒的核心概念响应式编程。笔者后面还会陆续有些文章,之后也会陆续介绍些自己对RAC核心类的理解,也希望各位对RAC框架有更多了解的大神们可以多多指教~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: