我正在尝试使用 ReactiveCocoa 实现 UITextFieldDelegate textFieldShouldReturn 处理。不幸的是,当我订阅信号时,subscribeNext block 正在运行。
使用委托(delegate)的实现是:
- (void)viewDidLoad
{
...
self.myTextField.delegate = self;
}
...
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == self.myTextField) {
NSLog(@"Let's go!");
}
return YES;
}
在 ReactiveCocoa 中,我以类似 UITextView+RACSignalSupport 的方式为 UITextField 添加了一个类别。
@implementation UITextField (RACKeyboardSupport)
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:)]]
takeUntil:self.rac_willDeallocSignal]
setNameWithFormat:@"%@ -rac_keyboardReturnSignal", [self rac_description]];
RACUseDelegateProxy(self);
return signal;
}
@end
即使没有按下 Return 键,subscribeNext block 也会执行:
- (void)viewDidLoad
{
...
[self.myTextField.rac_keyboardReturnSignal subscribeNext:^(id x) {
Log(@"Let's go with RAC!");
}];
}
我必须使用 skip:1 来避免这个问题:
- (void)viewDidLoad
{
...
[[self.myTextField.rac_keyboardReturnSignal skip:1] subscribeNext:^(id x) {
Log(@"Let's go with RAC!");
}];
}
知道为什么会这样吗?
解决方案:
- (RACSignal *)rac_keyboardReturnSignal
{
RACSignal *signal = [[[self.rac_delegateProxy
signalForSelector:@selector(textFieldShouldReturn:)]
takeUntil:self.rac_willDeallocSignal]
setNameWithFormat:@"%@ -rac_keyboardReturnSignal", [self rac_description]];
RACUseDelegateProxy(self);
return signal;
}
最佳答案
您正在返回一个信号,该信号会立即在您的 defer
block 中返回一个值,然后在 textFieldShouldReturn
时将新值concat
到流中被调用。
UITextView+RACSignalSupport.m
中的代码正在调用 reduceEach
以返回从 UITextView
实例中提取的字符串值。 defer
仅用于在订阅时生成初始值。
基本上,我认为您的用例根本不需要 defer
。
关于ios - UITextFieldDelegate textFieldShouldReturn 与 ReactiveCocoa,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26408460/