2012-03-06 59 views
1

這是一個讓我有點bat and的東西,而且我的眼睛正在黯然失色。在iOS中加載視圖時發生的事件順序

我有一個導航控制器的應用程序。

查看A具有一些輸入字段和「繼續」按鈕,它加載視圖B

當我輕觸導航控制器其導致事件的左上角的「返回」按鈕的順序被解僱我「M沒有料到/理解

我的跟蹤顯示...

View B: viewWillDisappear 
View A: viewWillAppear 
View B: textFieldShouldEndEditing 

編輯 - 更詳細/代碼解釋我以前模糊的問題

從概念上講,以下方法一直運行良好,並通過了多輪QA測試。

總之,我正在使用textFieldShouldEndEditing來驗證文本字段。如果他們無效,我會保持對該領域的關注,並向他們展示什麼是錯誤的信息。一切都很好,驗證工作可以在用戶嘗試從一個領域到另一個領域之間進行。

下面的代碼有問題的情況是,如果有人輸入部分值,然後單擊BACK。整個應用程序中的所有UITextFields凍結(不允許輸入),並且在某些情況下應用程序崩潰。

我試圖讓我發佈初始問題的方法是創建一個private:BOOL isDisappearing;

,我可以在viewWillDisappear檢查(在大多數情況下火災之前textFieldShouldEndEditing),如果它是的,我會短路被燒成和凍結UITextFields /應用程序有問題的代碼。

這是工作在幾個視圖罰款,但在'視圖A:viewWillAppear'事件之前觸發textFieldShouldEndEditing下面(視圖B) - isDisappearing設置爲'NO'以某種方式和有問題的代碼是在射擊textFieldShouldEndEditing

我希望這可以幫助,你可以按照。我發現很難解釋沒有代碼 - 但我試圖把它縮小到恰恰相關。我希望這裏適合 - 我對社區很新。

代碼VIEW B:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)rangereplacementString:(NSString *)string 
{ 
    // Enforce max lengths 
    // The return key from the keyboard counts as a character, so we have to exempt it 
if (textField.tag == ROUTING_NUMBER_TAG) 
{ 
    NSUInteger newLength = [textField.text length] + [string length] - range.length; 
    return (newLength > 9 && ![string isEqualToString:@"\n"]) ? NO : YES;   
} 
else if (textField.tag == ACCOUNT_NUMBER_TAG) 
{ 
    NSUInteger newLength = [textField.text length] + [string length] - range.length; 
    return (newLength > 17 && ![string isEqualToString:@"\n"]) ? NO : YES;   
} 
return YES; 
} 

// textField validation 
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField 
{ 
if (isDisappearing) 

    return YES; 

//run fields through validators and display validation messages. 
//IF THEY DON’T PASS VALIDATION IM "HOLDING THEM HOSTAGE" BY KEEPING THE FOCUS ON THE UITEXTFIELD (returning NO) 

if (textField.tag == ROUTING_NUMBER_TAG) 
{ 
    if ([Utility isValidRoutingNumber:textField.text]== NO) 
    { 
     [[iToast makeText:NSLocalizedString(@"Enter valid routing number", @"")] show]; 
     return NO; 
    } 
    else 
    { //save it 
     extension.payment.routingNumber = routingNumber.text; 
    } 
} 
else if (textField.tag == ACCOUNT_NUMBER_TAG) 
{ 
    if ([Utility isValidAccountNumber:textField.text] == NO) 
    { 
     [[iToast makeText:NSLocalizedString(@"Enter valid account number", @"")] show]; 
     return NO; 
    } 
    else 
    { //save it 
     extension.payment.accountNumber = accountNumber.text; 
    } 
} 
return YES; 
} 


- (void)textFieldDidEndEditing:(UITextField *)textField 
{ 

//I do nothing here except nulling out the 'activefield' var I use to autoscroll the uiscrollview as the user taps around from field to field 

} 



- (void)viewWillAppear:(BOOL)animated 
{ 
[super viewWillAppear:animated]; 

//reset the bool so that when they come back we're back to the 'normal' state and validation will again be checked in textFieldShouldEndEditing 

isDisappearing = NO; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
[super viewDidAppear:animated]; 
} 


-(void)viewWillDisappear:(BOOL)animated 
{ 
TRC_ENTRY 
//set the bool to bypass validations in textFieldShouldEndEditing 

isDisappearing = YES; 
[super viewWillDisappear:animated]; 
} 

回答

2

除了消息順序明確定義或名稱強烈隱含的情況外,應避免依賴於任何特定順序。例如,對於任何給定的視圖,您可以合理地預期在調用-viewDidAppear之前調用-viewWillAppear,但不要指望以任何特定的順序調用某個視圖的-viewWillAppear,這些順序與發送到不同視圖的任何消息有關。

如果您需要幫助瞭解如何實施特定功能而不依賴於訂單,請詢問。但是,除非調用順序記錄在案或從方法名稱明顯可見,否則不要指望特定的順序。

更新:我不明白到底發生了什麼錯在您添加的代碼,但也許一些建議將幫助:

  1. 是您isDisappearing變量視圖控制器的實例變量,一個全局變量,還是什麼?如果它是一個實例變量,找出它是如何改變的。如果它是一個全局變量,那麼......不要這樣做。

  2. 請確保您注意到warning in the docs的效果是-textViewShouldEndEditing:只是建議性的,並且無論您返回什麼內容,該視圖都可能會停止編輯。

  3. 嘗試暫時刪除iToast的東西。如果事故仍然發生,至少你已經消除了這個問題的根源。如果停止發生,您將縮小搜索範圍。

  4. 確定崩潰的原因。 (這真的應該是名單上的第一名。)崩潰不僅發生在神祕的地方 - 它的發生是有原因的。找到原因,你完成了85%。從發生崩潰時檢查堆棧跟蹤開始。如果這樣不能提供足夠的線索,請在引起崩潰的行之前的某個位置放置一個斷點,然後開始步進,直到崩潰。如果一切都失敗了,開始記錄消息來追蹤執行並監控你的假設。

  5. 你的視圖控制器A在-viewWillAppear方法中做了什麼?這可能是問題的一部分嗎?你可以將代碼移動到-viewDidAppear嗎?

+0

只是意外地提出我的意見過早。讓我再試一次......我的問題似乎是UITextFieldDelate相關事件以意想不到的方式發射。我確信有一個合乎邏輯的原因,但在某些情況下,textFieldShouldEndEditing * only *在UITextField具有焦點時單擊NavController「返回」按鈕時觸發。我的代碼在這種情況下工作。我剛剛發現textFieldDidEndEditing也在我遇到問題的情況下發射。我現在試圖弄清楚爲什麼DID在這個特定的情況下發射,但不是其他人。 – jaySF 2012-03-06 01:15:56

+0

@jayboston'-textFieldShouldEndEditing:'應該在文本字段即將放棄其「第一響應者」狀態時調用。因此,如果您點擊不同的文本字段,或者執行其他任何可以使文本字段不再成爲第一響應者的地方,則應該調用當前的焦點文本字段。這顯然包括點擊「後退」按鈕,因爲這將取代大部分響應者鏈,包括第一響應者。當文本字段確實停止爲第一響應者時,你有沒有調用'-textFieldDidEndEditing:'不* *的情況? – Caleb 2012-03-06 01:43:28

+0

@jayboston此外,請記住,如果您有多個具有相同代表的文本字段,該對象將接收所有文本字段的消息。所以你可能會得到一個字段的「-textFieldShouldBeginEditing:」和一個不同的字段或其他組合的「-textFieldDidEndEditing:」,而不一定按照這個順序。密切關注'sender'參數。 – Caleb 2012-03-06 01:46:28

0

嘗試在視圖B之前viewWillDisappear做[self.youTextField resignFirstResponder]

0

這可能不是你的問題直接相關,但如果你覺得自己不完全理解的觀點一輩子,我建議看看這裏:What is the process of a UIViewController birth (which method follows which)?

這是一個很好的解釋。

+0

謝謝。我對視圖生命週期非常瞭解。我遇到的問題似乎是textField事件發揮作用的時候。我正在使用UITextFieldDelegate並在這些事件中處理了很多字段驗證 – jaySF 2012-03-06 01:10:33

相關問題