zoukankan      html  css  js  c++  java
  • 函数响应式编程及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[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

    #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(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

    #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(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

    #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(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

    #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(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

    #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

    这个也是一样就不举例了

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

  • 相关阅读:
    cxGrid 锁定列
    精选网站
    Delphi XE10 dxLayoutControl 控件应用指南
    合并当前工作簿下的所有工作表
    【集中工作薄】 当前文件夹中所有Excel文件中 多个工作簿的第一个工作表 复制到工作簿中
    CxGrid如何实现导出Excel 功能
    Google Material Design的图标字体使用教程
    Mui沉浸模式以及状态栏颜色改变
    移动端弹性效果
    JS中的“!!”
  • 原文地址:https://www.cnblogs.com/zhouxihi/p/7237226.html
Copyright © 2011-2022 走看看