ReactiveCocoa之UI篇,reactivecocoaui
前言:
上一篇講ReactiveCocoa是函數響應式編程,並將多種事件響應的方式統一起來,使得不同的事件回應程式式高度統一。同時也講了ReactiveCocoa架構裡面常見的幾個概念。接下來基於那幾個概念來看看UI開發中的幾個應用。
實戰:1,替換了UIButton的target-Action:
1 [[self.btn rac_signalForControlEvents:(UIControlEventTouchUpInside)] subscribeNext:^(id x) {2 NSLog(@"點擊了button");3 }];
到rac_signalForControlEvents方法裡面查看這個方法做的操作:
1 - (RACSignal *)rac_signalForControlEvents:(UIControlEvents)controlEvents { 2 @weakify(self); 3 4 return [[RACSignal 5 createSignal:^(id<RACSubscriber> subscriber) { 6 @strongify(self); 7 8 [self addTarget:subscriber action:@selector(sendNext:) forControlEvents:controlEvents]; 9 [self.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{10 [subscriber sendCompleted];11 }]];12 13 return [RACDisposable disposableWithBlock:^{14 @strongify(self);15 [self removeTarget:subscriber action:@selector(sendNext:) forControlEvents:controlEvents];16 }];17 }]18 setNameWithFormat:@"%@ -rac_signalForControlEvents: %lx", RACDescription(self), (unsigned long)controlEvents];19 }
可以看到建立了一個RACSignal訊號並在block回調的時候執行操作為按鈕添加了監聽。此方法返回一個RACSignal訊號,同時我們在外界調用subscribeNext訂閱這個訊號,當點擊按鈕的時候調用sendNext方法發送值出來就回調了subscribeNext的block。
2,綁定textView的監聽(使用textfield同樣的道理)
1 [self.myTextView.rac_textSignal subscribeNext:^(id x) {2 NSLog(@"輸出:%@",x);3 }];
3,綁定手勢:
1 UITapGestureRecognizer *tap = [UITapGestureRecognizer new];2 [self.redView addGestureRecognizer:tap];3 [tap.rac_gestureSignal subscribeNext:^(id x) {4 NSLog(@"點擊了紅色的view");5 }];
可以感到一些比較平常的UI控制項基於 ReactiveCocoa上使用起來還是比較簡單的,這裡值得說一下的是當UI控制項是代理方式來監聽響應過程的時候。比如UIImagePicker。下面代碼實現一個簡單的小功能,點擊按鈕選擇圖片,圖片選擇好了之後顯示在UIImageView上面。
4,替換UI控制項的代理回調:
1 [[self.btn rac_signalForControlEvents:(UIControlEventTouchUpInside)] subscribeNext:^(id x) { 2 3 //點擊按鈕彈出UIImagePicker 4 self.imagePicker = [UIImagePickerController new]; 5 [self.imagePicker.rac_imageSelectedSignal subscribeNext:^(id x) { 6 //該block回調是在照片選擇完成的時候調用 7 NSLog(@"%@",x); 8 NSDictionary *dic = (NSDictionary *)x; 9 self.myImageView.image = dic[@"UIImagePickerControllerOriginalImage"];10 [self.imagePicker dismissViewControllerAnimated:YES completion:nil];11 }];12 //rac_delegateproxy是RAC下的代理屬性,這行代碼可以理解為,RAC下的代理將會執行block回調替換之前的代理去執行imagePickerControllerDidCancel方法
13 [[self.imagePicker.rac_delegateProxy signalForSelector:@selector(imagePickerControllerDidCancel:)] subscribeNext:^(id x) {
14 //該block調用時候:當delegate要執行imagePickerControllerDidCancel
15 [self.imagePicker dismissViewControllerAnimated:YES completion:nil];
16 }];
17
18 [self presentViewController:self.imagePicker animated:YES completion:nil]; 19 20 21 }];
5,RAC下的通知:
第一個頁面註冊通知:
1 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"ChangeColor" object:nil] subscribeNext:^(id x) {2 NSNotification *notification = (NSNotification *)x;3 NSLog(@"收到通知:%@",notification.object);4 self.view.backgroundColor = (UIColor *)notification.object;5 }];
第二個頁面中返回按鈕發送通知:
[[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeColor" object:[UIColor grayColor]];
6,RAC下的觀察者設計模式:
currentValue是視圖控制器擁有的一個Int類型的屬性.觀察該屬性的變化
[[self rac_valuesAndChangesForKeyPath:@"currentValue" options:(NSKeyValueObservingOptionNew) observer:self] subscribeNext:^(id x) { //解包元組,會把元組裡面的值按順序給變數賦值 RACTupleUnpack(NSString *kind,NSString *new) = x; NSLog(@"觀察到currentValue的值發生改變,現在的value等於%@,%@",kind,new); }];
按鈕點擊改變currentValue的值
[[self.valueButton rac_signalForControlEvents:(UIControlEventTouchUpInside)] subscribeNext:^(id x) { self.currentValue ++; }];
原始碼地址:https://github.com/SZT0728/ReactiveCocoaProgram
可以看到RAC下的UI高度統一了多種事件響應成block回調的方式。文章不精髓,只希望能夠記下自己學習的點滴並以最簡單的形式分享出來。若有不當之處,請指出。