美文网首页ios
RAC给UITextField添加代理回调

RAC给UITextField添加代理回调

作者: Dawn_wdf | 来源:发表于2020-03-08 03:36 被阅读0次

    使用RAC监听UITextField的文本可以用rac_textSignal,但是rac_textSignal是实时监控,如果我想等待UITextField输入完毕,即调用textFieldDidEndEditing:时发送信号,目前RAC中并没有支持,我参考RAC中UITextView+RACSignalSupport.h改写了一版。代码如下:
    .h

    //
    //  UITextField+ RACDelegateSignalSupport.h
    //  Snatch
    //
    //  Created by DawnWang on 2020/3/6.
    //  Copyright © 2020 Dawn Wang. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface UITextField (RACDelegateSignalSupport)
    - (RACSignal *)rac_keyboardReturnSignal;
    - (RACSignal *)rac_textFieldDidEndEditing;
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    .m

    //
    //  UITextField+ RACDelegateSignalSupport.m
    //  Snatch
    //
    //  Created by DawnWang on 2020/3/6.
    //  Copyright © 2020 Dawn Wang. All rights reserved.
    //
    
    #import "UITextField+ RACDelegateSignalSupport.h"
    #import <objc/runtime.h>
    #import <ReactiveObjC/ReactiveObjC.h>
    #import "NSObject+RACDescription.h"
    
    @interface UITextField()
    
    @property (nonatomic, weak) RACDelegateProxy *rac_delegateProxy;
    
    @end
    
    @implementation UITextField (RACDelegateSignalSupport)
    
    static void RACUseDelegateProxy(UITextField *self) {
        if (self.delegate == self.rac_delegateProxy) return;
    
        self.rac_delegateProxy.rac_proxiedDelegate = self.delegate;
        self.delegate = (id)self.rac_delegateProxy;
    }
    
    - (RACDelegateProxy *)rac_delegateProxy {
        RACDelegateProxy *proxy = objc_getAssociatedObject(self, _cmd);
        if (proxy == nil) {
            proxy = [[RACDelegateProxy alloc] initWithProtocol:@protocol(UITextFieldDelegate)];
            objc_setAssociatedObject(self, _cmd, proxy, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }
    
        return proxy;
    }
    
    - (RACSignal *)rac_keyboardReturnSignal {
        
        @weakify(self);
        RACSignal *signal = [[[[[RACSignal defer:^{
            @strongify(self);
               
            return [RACSignal return:RACTuplePack(self)];
        }]
                                concat:[self.rac_delegateProxy signalForSelector:@selector(textFieldShouldReturn:)]]
                               reduceEach:^(UITextField *x) {
        //因为此信号的本质是重置了代理,所以如果直接return X,原来代理方法则不执行,添加如下方法让原来的代理去执行,rac_textFieldDidEndEditing信号量同理。
        //让原来的代理也执行的原因是,我在自定义的view中添加了textfield并设置代理,希望点击return键的时候处理一些统一的事件,比如[textField resignFirstResponder];,
       //而在VC中配置了信号量处理特殊的业务逻辑。这样就可以在处理不同的业务逻辑之前,先处理统一的业务。
            @strongify(self);
            __autoreleasing id delegate = self.rac_delegateProxy.rac_proxiedDelegate;
            if ([delegate respondsToSelector:@selector(textFieldShouldReturn:)]) {
                [delegate textFieldShouldReturn:x];
            }
            return x;
        }]
                              takeUntil:self.rac_willDeallocSignal]
                             setNameWithFormat:@"%@ -rac_keyboardReturnSignal", RACDescription(self)];
        RACUseDelegateProxy(self);
                          
                           
        return signal;
    }
    
    - (RACSignal *)rac_textFieldDidEndEditing {
        @weakify(self);
         RACSignal *signal = [[[[[RACSignal
             defer:^{
                 @strongify(self);
                 return [RACSignal return:RACTuplePack(self)];
             }]
             concat:[self.rac_delegateProxy signalForSelector:@selector(textFieldDidEndEditing:)]]
                               reduceEach:^(UITextField *x) {
             @strongify(self);
             __autoreleasing id delegate = self.rac_delegateProxy.rac_proxiedDelegate;
             if ([delegate respondsToSelector:@selector(textFieldDidEndEditing:)]) {
                 [delegate textFieldDidEndEditing:x];
             }
                                   return x;
                               }]
                               takeUntil:self.rac_willDeallocSignal]
             setNameWithFormat:@"%@ -rac_textFieldDidEndEditing", RACDescription(self)];
    
         
         RACUseDelegateProxy(self);
                           
                            
         return signal;
    }
    
    @end
    

    相关文章

      网友评论

        本文标题:RAC给UITextField添加代理回调

        本文链接:https://www.haomeiwen.com/subject/fbfrdhtx.html