UITextFieldDelegate textFieldShould返回与ReactiveCocoa

问题描述:

我想实现UITextFieldDelegate textFieldShouldReturn与ReactiveCocoa处理。不幸的是,当我订阅信号时,subscribeNext块会运行。UITextFieldDelegate textFieldShould返回与ReactiveCocoa

使用代表团将实施:

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

这里块被执行,即使是从来没有按下回车键subscribeNext:

- (void)viewDidLoad 
{ 
    ... 
    [self.myTextField.rac_keyboardReturnSignal subscribeNext:^(id x) { 
     Log(@"Let's go with RAC!"); 
    }]; 
} 

我必须使用跳跃: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块返回的值的信号,当调用textFieldShouldReturn然后concat -ing新值到流。

UITextView+RACSignalSupport.m中的代码调用reduceEach以便返回从UITextView实例中提取的字符串值。 defer仅用于订阅时生成的初始值。

基本上,我认为你根本不需要defer作为你的用例。