RAC雙向綁定UITextField的正確姿勢(shì)

RAC雙向綁定UITextField的正確姿勢(shì)


一句話概括文章內(nèi)容

UITextField使用RACChannelTo的情況

  • 問題描述

直接使用RACChannelTo實(shí)現(xiàn)
UITextField的雙向綁定是有隱患的

  • 問題展示
    // 使用RACChannelTo雙向綁定
    RACChannelTo(self, string) = RACChannelTo(self.textField, text);
    
    // 結(jié)果1:通過鍵盤給self.textField.text賦值的情況
    // self.textField.text 改變 self.string 不改變
    // self.string 改變 self.textField.text 改變
    
    // 結(jié)果2:通過代碼給self.textField.text賦值的情況
    eg: `self.textField.text = @"123";` // 通過代碼賦值
    // self.textField.text 改變 self.string 改變
    // self.string 改變 self.textField.text 改變
    
  • 問題結(jié)論

    使用RACChannelTo(self.textField, text),
    當(dāng)通過code改變self.textField. text的值的時(shí)候
    才會(huì)把這個(gè)值發(fā)送出去


UITextField使用rac_newTextChannel的情況

  • 問題描述

直接使用rac_newTextChannel實(shí)現(xiàn)
UITextField的雙向綁定是有隱患的

  • 問題展示
    // 使用rac_newTextChannel雙向綁定
    RACChannelTo(self, string) = self.textField.rac_newTextChannel;
    
    // 結(jié)果1:通過鍵盤給self.textField.text賦值的情況
    // self.textField.text 改變 self.string 改變
    // self.string 改變 self.textField.text 改變
    
    // 結(jié)果2:通過代碼給self.textField.text賦值的情況
    eg: `self.textField.text = @"123";` // 通過代碼賦值
    // self.textField.text 改變 self.string 不改變
    // self.string 改變 self.textField.text 改變
    
  • 問題結(jié)論

    使用self.textField.rac_newTextChannel,
    當(dāng)通過鍵盤改變self.textField. text的值的時(shí)候
    才會(huì)把這個(gè)值發(fā)送出去


問題總結(jié)

無論是使用RACChannelTo還是rac_newTextChannel

self.string的值改變的時(shí)候,

self.textField.text都會(huì)跟著改變

也就是說

self.string -> self.textField.text 的這個(gè)單向通道是沒問題的

問題就在
無論是通過鍵盤或者code賦值來改變textField.text的值的時(shí)候,我們都要讓綁定的string對(duì)應(yīng)的改變,這才是我們要的雙向綁定

RACChannelTo rac_newTextChannel
當(dāng)通過code改變self.textField.text的值的時(shí)候才會(huì)把這個(gè)值發(fā)送出去 當(dāng)通過鍵盤改變self.textField. text的值的時(shí)候才會(huì)把這個(gè)值發(fā)送出去

解決方案

  • 錯(cuò)誤做法 -- rac_textSignal作祟導(dǎo)致

RACChannelTo(self, string) = self.textField.rac_newTextChannel;

此方式雙向綁定存在問題:通過code改變self.textField.text的值時(shí),不會(huì)發(fā)送值出去,導(dǎo)致綁定string失敗

因?yàn)槲覀冡槍?duì)這個(gè)痛點(diǎn)來解決

    
     RACChannelTo(self, string) = self.textField.rac_newTextChannel;
    @weakify(self);
    // 當(dāng) self.textField.text改變的時(shí)候,會(huì)回調(diào)這個(gè)block,然后再給string賦值,實(shí)現(xiàn)雙向綁定
    [self.textField.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
        @strongify(self);
        self.string = x;
    }];

結(jié)果: 當(dāng)self.textField.text = @"12312";code賦值的時(shí)候,self.textField.rac_textSignal不會(huì)觸發(fā)回調(diào)

原因rac_textSignal這個(gè)signal是監(jiān)聽UIControlEventAllEditingEvents的,所以對(duì)setter方式不會(huì)觸發(fā)signal(setter方式就是 屬性A = @"123"

- (RACSignal *)rac_textSignal {
   @weakify(self);
   return [[[[[RACSignal
       defer:^{
           @strongify(self);
           return [RACSignal return:self];
       }]
       concat:[self rac_signalForControlEvents:UIControlEventAllEditingEvents]]
       map:^(UITextField *x) {
           return x.text;
       }]
       takeUntil:self.rac_willDeallocSignal]
       setNameWithFormat:@"%@ -rac_textSignal", self.rac_description];
}

rac_textSignal的實(shí)現(xiàn),從中主要看到

 
concat:[self rac_signalForControlEvents:UIControlEventAllEditingEvents]]

// concat: 連接信號(hào),第一個(gè)信號(hào)必須發(fā)送完成,第二個(gè)信號(hào)才會(huì)被激活
// 也就是說,必須觸發(fā)UIControlEventAllEditingEvents才會(huì)觸發(fā)rac_textSignal,所以用setter的方式賦值就gg了

  • 正確做法

RACChannelTo(self, string) = RACChannelTo(self.textField, text);

此方式雙向綁定存在問題:通過鍵盤改變self.textField.text的值時(shí),不會(huì)發(fā)送值出去,導(dǎo)致綁定string失敗

因?yàn)槲覀冡槍?duì)這個(gè)痛點(diǎn)來解決

    
    RACChannelTo(self, string) = RACChannelTo(self.textField, text);
    @weakify(self);
    [self.textField.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
        @strongify(self);
        self.string = x;
    }];

簡(jiǎn)化代碼

    RACChannelTo(self, string) = RACChannelTo(self.textField, text);
    [self.textField.rac_textSignal subscribe:RACChannelTo(self, string)];

結(jié)語

UITextView的情況及處理跟UITextField一樣
對(duì)于整篇文章雙向綁定的分析,主要圍繞三個(gè)點(diǎn)

  • string -> textField.text
  • 鍵盤改變textField.text -> string
  • code賦值textField.text -> string

滿足上面三點(diǎn)就算完全的雙向綁定

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容