函数响应式编程及ReactiveObjC学习笔记 (四)
今天我们继续看其他的类别
UIImagePickerController+RACSignalSupport.h
#import <UIKit/UIKit.h> @class RACDelegateProxy;
@class RACSignal<__covariant ValueType>; NS_ASSUME_NONNULL_BEGIN @interface UIImagePickerController (RACSignalSupport) @property (nonatomic, strong, readonly) RACDelegateProxy *rac_delegateProxy; - (RACSignal<NSDictionary *> *)rac_imageSelectedSignal; @end NS_ASSUME_NONNULL_END
可以看到它有一个代理属性, 一个信号
再看下它有帮我们代理哪些方法
- (RACSignal *)rac_imageSelectedSignal {
RACSignal *pickerCancelledSignal = [[self.rac_delegateProxy
signalForSelector:@selector(imagePickerControllerDidCancel:)]
merge:self.rac_willDeallocSignal];
RACSignal *imagePickerSignal = [[[[self.rac_delegateProxy
signalForSelector:@selector(imagePickerController:didFinishPickingMediaWithInfo:)]
reduceEach:^(UIImagePickerController *pickerController, NSDictionary *userInfo) {
return userInfo;
}]
takeUntil:pickerCancelledSignal]
setNameWithFormat:@"%@ -rac_imageSelectedSignal", RACDescription(self)];
RACUseDelegateProxy(self);
return imagePickerSignal;
}
一个取消按钮的代理, 一个选择完毕的代理,
我们用来试试看
// 创建一个RACDelegateProxy
RACDelegateProxy *imgPickerDelegateProxy = [[RACDelegateProxy alloc] initWithProtocol:@protocol(UIImagePickerControllerDelegate)]; // 绑定取消代理事件
[[imgPickerDelegateProxy
rac_signalForSelector:@selector(imagePickerControllerDidCancel:)]
subscribeNext:^(RACTuple * _Nullable x) { NSLog(@"取消代理: %@", x);
UIImagePickerController *imgPicker = x[];
[imgPicker dismissViewControllerAnimated:YES completion:nil];
}]; // 绑定选择完毕事件
[[imgPickerDelegateProxy
rac_signalForSelector:@selector(imagePickerController:didFinishPickingImage:editingInfo:)]
subscribeNext:^(RACTuple * _Nullable x) { NSLog(@"选择完成: %@", x);
self.view.backgroundColor = [UIColor colorWithPatternImage:x[]]; UIImagePickerController *imgPicker = x[];
[imgPicker dismissViewControllerAnimated:YES completion:nil];
}]; // 创建UIImagePickerController
UIImagePickerController *imgPickerController = [[UIImagePickerController alloc] init];
imgPickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imgPickerController.allowsEditing = YES; // 设置代理为我们创建的delegateProxy
// 这里注意一般UIImagePickerController需要实现UIImagePickerDelegate & UINavigationControllerDelegate, 但这里用RAC自带的方法只能设置一个代理
// 不过其实RAC其实也只为UIImagePickerController处理了UIImagePickerControllerDelegate而已, 所以这里会有警告先不管它
// 后面我们再想想其他方式, 是重新写一个UIImagePickerController分类还是重写方法什么的 imgPickerController.delegate = (id<UIImagePickerControllerDelegate>)imgPickerDelegateProxy; // retain delegateProxy
objc_setAssociatedObject(imgPickerController, _cmd, imgPickerDelegateProxy, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [self presentViewController:imgPickerController animated:YES completion:nil];
这里大家需要注意下红色字体部分,
点击取消返回的x是imgPickerController本身, 转义后直接拿来dismiss即可
选择图片后x是一个数组, 第一个是imgPickerComtroller, 第二个是选择的image
UISegmentedControl+RACSignalSupport.h
#import <UIKit/UIKit.h> @class RACChannelTerminal<ValueType>; NS_ASSUME_NONNULL_BEGIN @interface UISegmentedControl (RACSignalSupport) - (RACChannelTerminal<NSNumber *> *)rac_newSelectedSegmentIndexChannelWithNilValue:(nullable NSNumber *)nilValue; @end NS_ASSUME_NONNULL_END
可以把分段选择器的选择结果直接绑定给其他空间, 或者拿去做别的 实例代码如下:
// 创建一个UISegementController
UISegmentedControl *segmentController = [[UISegmentedControl alloc] initWithItems:@[@"One", @"Two"]];
segmentController.frame = CGRectMake(, , , );
segmentController.center = self.view.center; [self.view addSubview:segmentController]; // 创建一个UITextField
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(, , , )];
textField.center = CGPointMake(self.view.center.x, self.view.center.y + );
textField.layer.borderWidth = ;
textField.layer.borderColor = [UIColor blueColor].CGColor; [self.view addSubview:textField]; // 获取segement的channelTerminal
RACChannelTerminal *segmentTerminal = [segmentController rac_newSelectedSegmentIndexChannelWithNilValue:]; // 获取textField的channelTerminal
RACChannelTerminal *textFieldTerminal = [textField rac_newTextChannel]; // 把segementdeterminal结果处理后绑定给textfieldTerminal
[[segmentTerminal
map:^id _Nullable(id _Nullable value) { if ([value isEqual: @()]) { return @"选择了: Two";
} else { return @"选择了: One";
}
}]
subscribe:textFieldTerminal];
UISlider+RACSignalSupport.h
#import <UIKit/UIKit.h> @class RACChannelTerminal<ValueType>; NS_ASSUME_NONNULL_BEGIN @interface UISlider (RACSignalSupport) - (RACChannelTerminal<NSNumber *> *)rac_newValueChannelWithNilValue:(nullable NSNumber *)nilValue; @end NS_ASSUME_NONNULL_END
跟UISegement一样, 我们直接给上代码:
// 创建一个UISlider
UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
slider.center = self.view.center; [self.view addSubview:slider]; // 创建一个UITextField
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(, , , )];
textField.center = CGPointMake(self.view.center.x, self.view.center.y + );
textField.layer.borderWidth = ;
textField.layer.borderColor = [UIColor blueColor].CGColor; [self.view addSubview:textField]; // 获取slider的channelTerminal
RACChannelTerminal *sliderTerminal = [slider rac_newValueChannelWithNilValue:]; // 获取textField的channelTerminal
RACChannelTerminal *textFieldTerminal = [textField rac_newTextChannel]; [[sliderTerminal
map:^id _Nullable(id _Nullable value) { return [NSString stringWithFormat:@"%@", value];
}]
subscribe:textFieldTerminal];
运行截图:

UIStepper+RACSignalSupport.h
#import <UIKit/UIKit.h> @class RACChannelTerminal<ValueType>; NS_ASSUME_NONNULL_BEGIN @interface UIStepper (RACSignalSupport) - (RACChannelTerminal<NSNumber *> *)rac_newValueChannelWithNilValue:(nullable NSNumber *)nilValue; @end NS_ASSUME_NONNULL_END
也是只有一个RACChannelTerminal, 我们直接上代码:
// 创建一个UIStepper
UIStepper *stepper = [[UIStepper alloc] initWithFrame:CGRectMake(, , , )];
stepper.center = self.view.center; [self.view addSubview:stepper]; // 创建一个UITextField
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(, , , )];
textField.center = CGPointMake(self.view.center.x, self.view.center.y + );
textField.layer.borderWidth = ;
textField.layer.borderColor = [UIColor blueColor].CGColor; [self.view addSubview:textField]; // 获取stepper的channelTerminal
RACChannelTerminal *stepperTerminal = [stepper rac_newValueChannelWithNilValue:]; // 获取textField的channelTerminal
RACChannelTerminal *textFieldTerminal = [textField rac_newTextChannel]; [[stepperTerminal
map:^id _Nullable(id _Nullable value) { return [NSString stringWithFormat:@"%@", value];
}]
subscribe:textFieldTerminal];
运行截图:

UISwitch+RACSignalSupport.h
#import <UIKit/UIKit.h> @class RACChannelTerminal<ValueType>; NS_ASSUME_NONNULL_BEGIN @interface UISwitch (RACSignalSupport) - (RACChannelTerminal<NSNumber *> *)rac_newOnChannel; @end NS_ASSUME_NONNULL_END
示例:
// 创建一个UISwitch
UISwitch *aswitch = [[UISwitch alloc] initWithFrame:CGRectMake(, , , )];
aswitch.center = self.view.center; [self.view addSubview:aswitch]; // 创建一个UITextField
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(, , , )];
textField.center = CGPointMake(self.view.center.x, self.view.center.y + );
textField.layer.borderWidth = ;
textField.layer.borderColor = [UIColor blueColor].CGColor; [self.view addSubview:textField]; // 获取aswitch的channelTerminal
RACChannelTerminal *aswitchTerminal = [aswitch rac_newOnChannel]; // 获取textField的channelTerminal
RACChannelTerminal *textFieldTerminal = [textField rac_newTextChannel]; [[aswitchTerminal
map:^id _Nullable(id _Nullable value) { if ([value boolValue]) { return @"";
} return @"";
}]
subscribe:textFieldTerminal];
UITableViewCell+RACSignalSupport.h
#import <UIKit/UIKit.h> @class RACSignal<__covariant ValueType>;
@class RACUnit; NS_ASSUME_NONNULL_BEGIN @interface UITableViewCell (RACSignalSupport) @property (nonatomic, strong, readonly) RACSignal<RACUnit *> *rac_prepareForReuseSignal; @end NS_ASSUME_NONNULL_END
有一个rac_prepareForReuseSignal属性, 看字面意思就很清除准备复用时调用
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
cell.textLabel.text = @"cell";
[[cell
rac_prepareForReuseSignal]
subscribeNext:^(RACUnit * _Nullable x) {
NSLog(@"开始复用");
}];
return cell;
}
UITableViewHeaderFooterView+RACSignalSupport.h
#import <UIKit/UIKit.h> @class RACSignal<__covariant ValueType>;
@class RACUnit; NS_ASSUME_NONNULL_BEGIN // This category is only applicable to iOS >= 6.0.
@interface UITableViewHeaderFooterView (RACSignalSupport) @property (nonatomic, strong, readonly) RACSignal<RACUnit *> *rac_prepareForReuseSignal; @end NS_ASSUME_NONNULL_END
这个也是一样就不举例了
今天先看这些, 后面我们再继续
函数响应式编程及ReactiveObjC学习笔记 (四)的更多相关文章
- 函数响应式编程及ReactiveObjC学习笔记 (-)
最近无意间看到一个视频讲的ReactiveObjC, 觉得挺好用的 但听完后只是了解个大概. 在网上找了些文章, 有的写的比较易懂但看完还是没觉得自己能比较好的使用RAC, 有的甚至让我看不下去 这两 ...
- 函数响应式编程及ReactiveObjC学习笔记 (二)
之前我们初步认识了RAC的设计思路跟实现方式, 现在我们再来看看如果使用它以及它能帮我们做什么 One of the major advantages of RAC is that it provid ...
- 函数响应式编程及ReactiveObjC学习笔记 (三)
之前讲了RAC如何帮我们实现KVO / 代理 / 事件 / 通知 今天先不去分析它的核心代码, 我们先看看ReactiveObjC库里面一些特别的东西, 如果大家点开ReactiveObjC目录应该 ...
- 函数响应式编程(FRP)框架--ReactiveCocoa
由于工作原因,有段时间没更新博客了,甚是抱歉,只是,从今天開始我又活跃起来了,哈哈,于是决定每周更新一博.大家互相学习.交流. 今天呢.讨论一下关于ReactiveCocoa,这个採用函数响应式编程( ...
- 函数响应式编程(FRP)—基础概念篇
原文出处:http://ios.jobbole.com/86815/. 一函数响应式编程 说到函数响应式编程,就不得不提到函数式编程,他们俩有什么关系呢?今天我们就详细的解析一下他们的关系. 现在下面 ...
- RxJS入门之函数响应式编程
一.函数式编程 1.声明式(Declarativ) 和声明式相对应的编程⽅式叫做命令式编程(ImperativeProgramming),命令式编程也是最常见的⼀种编程⽅式. //命令式编程: fun ...
- 函数响应式编程(FRP)思想-Callback风格
序 ReactiveCocoa是IOS广为使用的技术框架,而ReactiveCocoa的核心思想就FRP.FRP不同于JAVA的object-oriented和AOP,FRP能让你的代码像数学一样简洁 ...
- ReactiveCocoa,最受欢迎的iOS函数响应式编程库(2.5版),没有之一!
简介 项目主页: ReactiveCocoa 实例下载: https://github.com/ios122/ios122 简评: 最受欢迎,最有价值的iOS响应式编程库,没有之一!iOS MVVM模 ...
- 函数响应式编程(FRP)从入门到”放弃”——基础概念篇
前言 研究ReactiveCocoa一段时间了,是时候总结一下学到的一些知识了. 一.函数响应式编程 说道函数响应式编程,就不得不提到函数式编程,它们俩到底有什么关系呢?今天我们就详细的解析一下他们的 ...
随机推荐
- Eclipse导出JavaDoc中文乱码问题解决
在Eclipse里 export 选 JavaDoc,在向导的最后一页的Extra JavaDoc Options 里填上参数即可 比如项目采用的是UTF-8的编码就填:-encoding UTF-8 ...
- django ngRoute ui-router 开发环境下禁用缓存
问题描述: Python manage.py runserver ,禁用缓存,及时修改反馈到浏览器 解决办法: 使用dummy cache: Dummy caching (for developmen ...
- 如何在BCGControlBar界面库的CBCGPFormView子视图里面添加工具栏
最近有一个项目需求,需要在子视图里面添加一个新工具栏用来处理当前视图对应模块的操作.之前在对话框模式下做过添加工具栏的实现,在CBCGPFormView中添加工具栏还是头一次.在这里记录一下,给自己留 ...
- ubuntu 16.04.2 源码安装gitlab并且利用runner持续集成
参考原档:https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#using-https 本章只 ...
- jquery按钮倒计时
<html> <head> <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"> ...
- Appcan开发笔记:结合JQuery的$.Deferred()完善批量异步发送
appcan的 uexXmlHttpMgr.send 或者 appcan.ajax无法同步请求(没有找到这个属性),只能异步,造成循环多次提交时由于延迟或网络堵塞等原因无法同步响应,导致提交顺序混乱, ...
- 【Android Developers Training】 39. 获取文件信息
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- Ext template 的使用
Ext template 的使用 Ext.define('app.view.MyDataView', { extend: 'Ext.panel.Panel', xtype: 'myDataView', ...
- Java IO学习笔记(五)对象流
1.Object流:直接将Object写入或读出. 2.序列化:将Object直接转化成字节流写到硬盘或网络上. 3.如果想把一个对象转化成字节流,该对象的实体类必须得实现Serializable接口 ...
- 将HTML导出生成word文档
前言: 项目开发中遇到了需要将HTML页面的内容导出为一个word文档,所以有了这边随笔. 当然,项目开发又时间有点紧迫,第一时间想到的是用插件,所以百度了下.下面就介绍两个导出word文档的方法. ...