2014-04-03 41 views
2

我在反應可可中遇到了一些非常簡單的代碼問題,我無法理解我做錯了什麼。基於UITextField中的文本的反應可可啓用按鈕

我只是試圖將一個UIButton的啓用狀態綁定到一個信號。該信號採用UITextField的文本並通過正則表達式運行。這樣我可以在正則表達式匹配時啓用按鈕。

此代碼給了我一個異常而加載視圖控制器:

// Poperties used in the view controller 
@property (strong, nonatomic) NSRegularExpression *regex; 
@property (weak, nonatomic) IBOutlet UITextField *myTextField; 
@property (weak, nonatomic) IBOutlet UIButton *continueButton; 

// ... other stuff ... 

// Code in my "view did load" method 
RACSignal *mySignal = RACObserve(self, myTextField); 

[mySignal deliverOn:[RACScheduler mainThreadScheduler]]; 

@weakify(self); 
[mySignal map:^(NSString *value) { 
    @strongify(self); 
    NSUInteger matches = [self.regex numberOfMatchesInString:value 
                options:0 
                range:NSMakeRange(0, [value length])]; 
    return @(matches > 0); 
}]; 

RAC(self.continueButton, enabled) = mySignal; 

顯然例外解釋說,我試圖讓「啓用」從UITextField選擇,而UITextField沒有這個選擇。我不明白爲什麼我在調用continueButton而不是myTextField中的啓用選擇器時出現此錯誤。

基本上例外是:

[UITextField charValue]: unrecognized selector sent to instance 0xa2c7830 

並且調試器在停止線:

[object setValue:x ?: nilValue forKeyPath:keyPath]; 

實例0xa2c7830UITextFieldobjectUIButtonkeyPath@"enabled"。我只是沒有看到這個設置有什麼問題,除了它被我的UITextField而不是UIButton所調用!

感謝您的幫助!

回答

4

的暗示是在這裏:

[UITextField charValue] 

無法識別的選擇是不enabled;它是charValue。好的,爲什麼我們會要求UITextField變成char?那麼......如果我們想把它壓制成一個布爾值,那麼KVO機制可能會認爲它是一個NSNumber,並試圖將其視爲這樣。但它不是NSNumber - 因此是例外。

但是等等,我們是不是要映射信號來創建一個NSNumber?爲什麼我們試圖首先將它強制轉換爲布爾值?爲什麼它是UITextField而不是NSString? (我們稍後會回來)

啊。那麼,我們實際上並沒有將信號映射到其他東西上,因爲map:沒有破壞性。

我的意思是map:創建一個新的信號。它不修改mySignal。我們稱之爲map:,創造了一個新的信號,但我們從來沒有對它做過任何事情 - 它只是坐在那裏,沒有任何訂閱它,然後它被釋放。但我們想訂閱它!

RAC(self.continueButton, enabled) = [mySignal map:^(NSString *value) { 
    @strongify(self); 
    NSUInteger matches = [self.regex numberOfMatchesInString:value 
                options:0 
                range:NSMakeRange(0, [value length])]; 
    return @(matches > 0); 
}]; 

啊哈!現在我們將enabled屬性綁定到轉換後的信號 - 這正是我們一直想要的。但有些東西仍然是錯誤的。

當我們嘗試執行正則表達式匹配時會發生一些不好的事情...如果我不得不猜測[UITextField length]: unrecognized selector sent to instance 0xWhatever

UITextField again?這傢伙怎麼了?

回答於mySignalmySignal究竟是什麼發送?我們希望它發送文本......但如果我剛剛編制的新例外是正確的,那麼它會發送UITextField!爲什麼?那麼,mySignalRACObserve(self, myTextField)。可是等等!這將發送文本字段的新值 - 而不是文本字段文本的新值。你想要的是:

RACSignal *mySignal = self.myTextField.rac_textSignal; 

這將發送新的文本字段的文本值,而不是文本字段的新值。

Phew。這應該工作。作爲提示:log*助手對調試非常有用。

RAC(self.continueButton, enabled) = [mySignal logAll]; 

這會告訴你,mySignal正在發送UITextField!而非NSString秒。

+0

一個奇妙的解釋,非常感謝。這是最好的答案,因爲現在我明白了爲什麼它不起作用。現在感覺RAC更加舒適。再次感謝! –

相關問題