前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >函数响应式编程及ReactiveObjC学习笔记 (四)

函数响应式编程及ReactiveObjC学习笔记 (四)

作者头像
周希
发布2019-10-15 11:45:46
8650
发布2019-10-15 11:45:46
举报
文章被收录于专栏:APP自动化测试APP自动化测试

今天我们继续看其他的类别

UIImagePickerController+RACSignalSupport.h

代码语言:javascript
复制
#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

可以看到它有一个代理属性, 一个信号

再看下它有帮我们代理哪些方法

代码语言:javascript
复制
- (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;
}

一个取消按钮的代理, 一个选择完毕的代理,

我们用来试试看

代码语言:javascript
复制
// 创建一个RACDelegateProxy
    RACDelegateProxy *imgPickerDelegateProxy = [[RACDelegateProxy alloc] initWithProtocol:@protocol(UIImagePickerControllerDelegate)];
    
    // 绑定取消代理事件
    [[imgPickerDelegateProxy
     rac_signalForSelector:@selector(imagePickerControllerDidCancel:)]
     subscribeNext:^(RACTuple * _Nullable x) {
         
         NSLog(@"取消代理: %@", x);
         UIImagePickerController *imgPicker = x[0];
         [imgPicker dismissViewControllerAnimated:YES completion:nil];
     }];
    
    // 绑定选择完毕事件
    [[imgPickerDelegateProxy
        rac_signalForSelector:@selector(imagePickerController:didFinishPickingImage:editingInfo:)]
        subscribeNext:^(RACTuple * _Nullable x) {
            
            NSLog(@"选择完成: %@", x);
            self.view.backgroundColor = [UIColor colorWithPatternImage:x[1]];
            
            UIImagePickerController *imgPicker = x[0];
            [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

代码语言:javascript
复制
#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

可以把分段选择器的选择结果直接绑定给其他空间, 或者拿去做别的 实例代码如下:

代码语言:javascript
复制
// 创建一个UISegementController
    UISegmentedControl *segmentController = [[UISegmentedControl alloc] initWithItems:@[@"One", @"Two"]];
    segmentController.frame = CGRectMake(0, 0, 160, 40);
    segmentController.center = self.view.center;
    
    [self.view addSubview:segmentController];
    
    // 创建一个UITextField
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    textField.center = CGPointMake(self.view.center.x, self.view.center.y + 100);
    textField.layer.borderWidth = 1;
    textField.layer.borderColor = [UIColor blueColor].CGColor;
    
    [self.view addSubview:textField];
    
    // 获取segement的channelTerminal
    RACChannelTerminal *segmentTerminal = [segmentController rac_newSelectedSegmentIndexChannelWithNilValue:0];
    
    // 获取textField的channelTerminal
    RACChannelTerminal *textFieldTerminal = [textField rac_newTextChannel];
    
    // 把segementdeterminal结果处理后绑定给textfieldTerminal
    [[segmentTerminal
        map:^id _Nullable(id  _Nullable value) {
        
        if ([value  isEqual: @(1)]) {
            
            return @"选择了: Two";
        } else {
            
            return @"选择了: One";
        }
    }]
        subscribe:textFieldTerminal];

UISlider+RACSignalSupport.h

代码语言:javascript
复制
#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一样, 我们直接给上代码:

代码语言:javascript
复制
// 创建一个UISlider
    UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(0, 0, 200, 35)];
    slider.center = self.view.center;
    
    [self.view addSubview:slider];
    
    // 创建一个UITextField
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    textField.center = CGPointMake(self.view.center.x, self.view.center.y + 100);
    textField.layer.borderWidth = 1;
    textField.layer.borderColor = [UIColor blueColor].CGColor;
    
    [self.view addSubview:textField];
    
    // 获取slider的channelTerminal
    RACChannelTerminal *sliderTerminal = [slider rac_newValueChannelWithNilValue:0];
    
    // 获取textField的channelTerminal
    RACChannelTerminal *textFieldTerminal = [textField rac_newTextChannel];
    

    
    [[sliderTerminal
        map:^id _Nullable(id  _Nullable value) {
            
            return [NSString stringWithFormat:@"%@", value];
        }]
        subscribe:textFieldTerminal];

运行截图:

UIStepper+RACSignalSupport.h

代码语言:javascript
复制
#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, 我们直接上代码:

代码语言:javascript
复制
// 创建一个UIStepper
    UIStepper *stepper = [[UIStepper alloc] initWithFrame:CGRectMake(0, 0, 80, 35)];
    stepper.center = self.view.center;
    
    [self.view addSubview:stepper];
    
    // 创建一个UITextField
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    textField.center = CGPointMake(self.view.center.x, self.view.center.y + 100);
    textField.layer.borderWidth = 1;
    textField.layer.borderColor = [UIColor blueColor].CGColor;
    
    [self.view addSubview:textField];
    
    // 获取stepper的channelTerminal
    RACChannelTerminal *stepperTerminal = [stepper rac_newValueChannelWithNilValue:0];
    
    // 获取textField的channelTerminal
    RACChannelTerminal *textFieldTerminal = [textField rac_newTextChannel];
    

    [[stepperTerminal
        map:^id _Nullable(id  _Nullable value) {
            
            return [NSString stringWithFormat:@"%@", value];
        }]
        subscribe:textFieldTerminal];

运行截图:

UISwitch+RACSignalSupport.h

代码语言:javascript
复制
#import <UIKit/UIKit.h>

@class RACChannelTerminal<ValueType>;

NS_ASSUME_NONNULL_BEGIN

@interface UISwitch (RACSignalSupport)

- (RACChannelTerminal<NSNumber *> *)rac_newOnChannel;

@end

NS_ASSUME_NONNULL_END

示例:

代码语言:javascript
复制
// 创建一个UISwitch
    UISwitch *aswitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 60, 35)];
    aswitch.center = self.view.center;
    
    [self.view addSubview:aswitch];
    
    // 创建一个UITextField
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    textField.center = CGPointMake(self.view.center.x, self.view.center.y + 100);
    textField.layer.borderWidth = 1;
    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 @"1";
            }
            
            return @"0";
        }]
     subscribe:textFieldTerminal];

UITableViewCell+RACSignalSupport.h

代码语言:javascript
复制
#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属性, 看字面意思就很清除准备复用时调用

代码语言:javascript
复制
- (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

代码语言:javascript
复制
#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

这个也是一样就不举例了

今天先看这些, 后面我们再继续

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-07-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档