使用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
网友评论