我们平常所常用到的响应式编程有哪些:代理,通知,KVO,Block回调,Target,监听事件等
通过RAC我们可以更加简单的实现事件的方法,降低了代码的耦合度,更方便管理
RAC的优点:减少代码量,可灵活使用
RAC常用的几种用法:
KVO、textFiled、button - taget - event、delegate、通知、代替某个方法
RAC常用的高级用法:
过滤:filter、ignore、distinctUntilChanged、take、takeLast、takeUntil、takeWhileBlock、skip、switchToLatest
秩序:doNext、 docompleted
时间:retry、interval、delay
重复:retry、replay、throttle
其他方法:startWith
RAC的重要概念:
RACSignal、RACSubscriber、RACSubject
集成:
Objective-C:pod 'ReactiveCocoa', '2.1.8'
Swift:https://github.com/ReactiveCocoa
RAC: 信号 面向信号开发!!
1.创建信号!!
RACSubject *subject = [RACSubject subject];
2.谁对信号感兴趣,谁订阅信号(订阅者)
[subject subscribeNext:^(id x) {
NSLog(@"%@",x);//Hello RAC!!
}];
3.我发送信号
[subject sendNext:@"Hello RAC!!"];
代理
常用方法
1.定义一个方法
2.定义协议方法
3.定义一个代理属性(遵守这个协议)
4.当发生一些事情,我看看代理属性有没有值
5.看看代理有没有响应我的方法!
使用代理
1.设置代理
2.遵守协议
3.实现方法
//HKView页面
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
-(void)btnClick:(UIButton *)send
{
点击事件的处理过程
}
RAC方法
[[self.HkView rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(id x) {
点击事件的处理过程
}];
代理传值
//传值页面
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
-(void)btnClick:(UIButton *)send
{
[self sendContent:@"今天真开心!!"];
}
-(void)sendContent:(id)objc
{
//可以什么都不做
}
//数据显示和处理页面
[[self.HkView rac_signalForSelector:@selector(sendContent:)]subscribeNext:^(id x) {
NSLog(@"%@",x);//今天真开心
}];
KVO
监听view的frame的变化
平时写法
[self.hKView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"观察到了");
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.hKView.frame = CGRectMake(100, 100, 50, 50);
}
其他实例
// RACObserve(TARGET, KEYPATH):KVO,监听某个对象的属性,返回的是信号。
第一步:[self NotificationCenter];
第二步: [RACObserve(self.tabelView1, backgroundColor) subscribeNext:^(id _Nullable x) {
NSLog(@"self.view换了新背景颜色:%@",x);
}];
第三步:-(void)NotificationCenter
{
self.tabelView1.backgroundColor = [UIColor orangeColor];
}
[RACObserve(_tabelView1, contentOffset)subscribeNext:^(id x) {
//监听scrollview的滑动
NSLog(@"success:%@",x);
}];
//五秒后执行一次,延时执行
[[RACScheduler mainThreadScheduler]afterDelay:5 schedule:^{
NSLog(@"五秒后执行一次");
self.tabelView1.backgroundColor = [UIColor redColor];
}];
//每隔两秒执行一次
//这里要加takeUntil条件限制一下否则当控制器pop后依旧会执行
[[[RACSignal interval:2 onScheduler:[RACScheduler mainThreadScheduler]] takeUntil:self.rac_willDeallocSignal ] subscribeNext:^(id x) {
NSLog(@"每两秒执行一次");
}];
}
RAC写法
用来给某个对象的某个属性绑定信号,只要产生信号内容,就会将内容赋值给属性
//方法1:
[[self.hKView rac_valuesAndChangesForKeyPath:@"frame" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld observer:nil ]subscribeNext:^(id _Nullable x) {
NSLog(@"RAC观察到了");
}];
//方法2:
[[self.hKView rac_valuesForKeyPath:@"frame" observer:self]subscribeNext:^(id _Nullable x) {
NSLog(@"RAC观察到了");
}];
//方法3:
[RACObserve(self.hKView, frame) subscribeNext:^(id _Nullable x) {
NSLog(@"RAC观察到了");
}];
最大的好处是:当需要观察某个对象的某些属性时,简化了代码,使代码更好维护和阅读
监听事件
常用写法
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
-(void)btnClick:(UIButton *)send
{
NSLog(@"今天真开心!!");
}
RAC写法
//监听按钮的点击事件
[[btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
NSLog(@"今天真开心!!");
}];
通知
RAC通知传值
//RAC通知
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 在某个页面中我们需要发出通知,发送名为postdata的通知并传送一个数组dataArray
NSMutableArray *dataArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:dataArray];
}
//调用键盘的通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
//可处理键盘弹出时页面布局问题等
}];
UITextFiled
监听textFiled的输入
文本框实时的监听
[self.numTextF.rac_textSignal subscribeNext:^(NSString *x) {
NSLog(@"文本框输入的内容:%@" ,x);
}];
[self.nameTextF.rac_newTextChannel subscribeNext:^(id _Nullable x) {
NSLog(@"输出什么:%@",x);
}];
[[self.nameTextF rac_inputTextSignal]subscribeNext:^(id x) {
NSLog(@"打印2:%@",x);
}];
//RAC的实时赋值
RAC(_labe1, text) = _numTextF.rac_textSignal;
textFiled数字输入监听
[self.numTextF.rac_textSignal subscribeNext:^(NSString *x) {
static NSInteger const maxIntegerLength=8;//最大整数位
static NSInteger const maxFloatLength=2;//最大精确到小数位
if (x.length) {
//第一个字符处理
//第一个字符为0,且长度>1时
if ([[x substringWithRange:NSMakeRange(0, 1)] isEqualToString:@"0"]) {
if (x.length>1) {
if ([[x substringWithRange:NSMakeRange(1, 1)] isEqualToString:@"0"]) {
//如果第二个字符还是0,即"00",则无效,改为"0"
self.numTextF.text=@"0";
}else if (![[x substringWithRange:NSMakeRange(1, 1)] isEqualToString:@"."]){
//如果第二个字符不是".",比如"03",清除首位的"0"
self.numTextF.text=[x substringFromIndex:1];
}
}
}
//第一个字符为"."时,改为"0."
else if ([[x substringWithRange:NSMakeRange(0, 1)] isEqualToString:@"."]){
self.numTextF.text=@"0.";
}
//2个以上字符的处理
NSRange pointRange = [x rangeOfString:@"."];
NSRange pointsRange = [x rangeOfString:@".."];
if (pointsRange.length>0) {
//含有2个小数点
self.numTextF.text=[x substringToIndex:x.length-1];
}
else if (pointRange.length>0){
//含有1个小数点时,并且已经输入了数字,则不能再次输入小数点
if ((pointRange.location!=x.length-1) && ([[x substringFromIndex:x.length-1]isEqualToString:@"."])) {
self.numTextF.text=[x substringToIndex:x.length-1];
}
if (pointRange.location+maxFloatLengthmaxIntegerLength) {
self.numTextF.text=[x substringToIndex:maxIntegerLength];
}
}
}
}];
监听输入字体个数的简单处理
//监听输入字体个数
NSInteger maxLenght = 10;
[[self.nameTextF.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
return value.length > maxLenght;
}] subscribeNext:^(NSString * _Nullable x) {
// NSLog(@"最多输入10个文字");
self.nameTextF.text = [self.nameTextF.text substringToIndex:maxLenght];
}];
未完待续...