2013-02-04 71 views
0

我有我的應用程序內置以下視圖控制器。呈現控制器是「PatientSelectViewController」(我們稱之爲控制器A),它允許手動在文本字段中輸入患者ID,或者按下「掃描條形碼」按鈕,該按鈕將執行到另一個視圖控制器的繼續 - 即「BarcodeScanViewController 「(我們稱之爲控制器B)。麻煩協調視圖控制器

當B完成掃描條形碼並返回結果(患者ID)時,我通知呈現視圖控制器(A),A負責在數據庫中查找ID。此時控制器B應該被解僱。如果找到ID,那麼我們轉到第三個視圖控制器 - 「PatientConfirmViewController」(我們稱之爲C)。但是,如果沒有找到ID,那麼我需要彈出一條消息說明並再次返回控制器B再次掃描條形碼。同樣,如果用戶決定在文本字段中手動輸入ID而不是掃描它,那麼成功的ID會將我帶到控制器C,而不成功的ID會給出彈出消息並保留在控制器A中再試一次。

我也希望將控制器嵌入到導航控制器中,這樣我總是有tabbar按鈕,將我帶回前一個視圖控制器。例如,我將有一個tabbar按鈕從B或C返回到A.理想情況下,如果我在成功掃描條碼後到達C,我希望tabbar按鈕將我帶回B - 而不是A! - 如果用戶決定她不想確認這個ID,這個想法是用戶可能想要重新掃描一個條形碼。但這並不重要。

由於某種原因,我遇到了麻煩。下面是一個搞砸行爲的例子:我打電話A,然後調用B(掃描條形碼)並掃描我知道在數據庫中的條形碼。這正確地將我帶到了C,顯示了患者信息。但後來我決定回到A使用標籤欄按鈕「輸入病人ID」然後我再次按下「掃描條碼」按鈕,再次掃描相同的條形碼,但這次,而不是成功過渡到C,我越來越這個屏幕 - 注意搞砸了tabbar!它必須同時說「確認ID」和「輸入患者ID」,並且按鈕返回登錄(這是首先調用A的控制器)和「掃描條形碼」 - 即控制器B就好像它從未彈出過! screwed up tabbar 這可以在2次或3次或更多次成功掃描後隨機發生。日誌顯示此:

嵌套推動畫可導致損壞的導航欄

不平衡呼叫開始/結束的外觀轉變爲 。

完成導航 過渡處於意外狀態。導航欄子視圖樹可能會損壞 。

這裏是我是如何實現它:

鑑於控制器A:

-(void)prepareForSegue: (UIStoryboardSegue *)segue sender: (id)sender 
{ 
    if ([[segue identifier] isEqualToString:@"BarcodeScanView"]) 
    { 
     self.p_usingBarcodeScan=YES; 
     [[segue destinationViewController]setViewDelegate:self]; //sets itself as a delegate for receiving the result of a barcode scan from controller B 
    } 
    if ([[segue identifier] isEqualToString:@"ConfirmID"]) 
    { 
     [[segue destinationViewController] setP_userInfo:p_userInfo] ; //passes the data to the controller C 
    } 
} 

對(仍然在控制器A)接收條形碼掃描結果的委託方法:

- (void) didScanBarcode:(NSString *)result 
{ 

    self.p_userID = result; 

    [self.navigationController popViewControllerAnimated:YES];//Pop B from the navigation stack to return to A - is this right???? 

    //Run the database query 
    [self lookUpID]; 
} 

在數據庫中查找ID的方法(仍在A中):

- (void) lookUpID{ 


    /*..... 
    Does something here and gets a result of the lookup... 
    */ 

    // Do something with the result 
    if ([[result p_userName] length] > 0){ //Found the user! 
     p_userInfo = result; 
     [self performSegueWithIdentifier: @"ConfirmID" sender: self]; 

    } 
    else { 
     UIAlertView * messageDlg = [[UIAlertView alloc] initWithTitle:nil message:@"User was not found. Please try again" 
                  delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; 
     [messageDlg show]; 

     //Here I'd like to perform this seque to B only if I got here after a barcode scan... 
     //Otherwise I am just staying in A... 
     if (self.p_usingBarcodeScan == YES){ 
      [self performSegueWithIdentifier: @"BarcodeScanView" sender: self]; 
     } 
    } 
    return; 
} 

只是爲了保持完整性,B中有一次我設法掃描條形碼,我打電話這樣的:

- (void)decodeResultNotification: (NSNotification *)notification { 

    if ([notification.object isKindOfClass:[DecoderResult class]]) 
    { 
     DecoderResult *obj = (DecoderResult*)notification.object; 
     if (obj.succeeded) 
     { 
      decodeResult = [[NSString alloc] initWithString:obj.result]; 

      [[self viewDelegate] didScanBarcode:decodeResult]; 
     } 
    } 
} 

我使用推seques從A到B,從A到C和使用故事板。 這是故事板的快照,可以看到從A到B(「BarcodeScan」)和A到C(「ConfirmID」)的段落。兩者都是推塞格斯:

storyboard snapshot

非常感謝提前!

回答

0

好的,我想部分回答我自己的問題。 甚至在執行他的建議以上,我的煩惱依然存在,甚至相乘(關於這些的一些細節都在我的話題http://chat.stackoverflow.com/rooms/23918/discussion-between-peterd-and-he-was評論)

但是之後,一些變化我GOOGLE了我得到的日誌消息:「嵌套推動動漫可能導致損壞的導航欄」和清盤閱讀這樣的回答:https://stackoverflow.com/a/5616935/1959008,這表明,我的問題是使用

[self.navigationController popViewControllerAnimated:YES]; 

是與動畫設置爲YES。一旦我將它設置爲NO,Tabbar的問題就消失了(一些小怪異依然存在,我希望能儘快解決它們)。這真是奇怪 - 看起來更像是一個錯誤,而不是一個功能對我來說,但我當然可能是錯的...

0

你不會說你是否正在使用導航控制器,並推動賽格或呈現模態賽格。

這裏:

[self.navigationController popViewControllerAnimated:YES];//Pop B from the navigation stack to return to A - is this right???? 
    [self dismissViewControllerAnimated:YES completion:nil];**//is this right???** 

首先是從推送SEGUE返回正確的,第二個是適合於模態/呈遞SEGUE。當您在導航控制器中使用後退按鈕時,推回式方法實際上會發生什麼。

更新 我認爲你需要解決你的導航方法一點點。我建議什麼

  • 在B,有一個委託方法

    • 檢查病人ID
    • ,如果它在一個
    • 回報self.p_userID好的集的BOOL成功/失敗回到B
      _
  • 基於該結果, :

    • 彈出自己關(您可以直接在B之間使用[self.navigationController popViewController])或

    • 帶給你警示B中。假設您在B中有後退按鈕,並且(可能)重新掃描按鈕,則您的警報可能不需要提供任何選擇。

一個

- (void) viewWillAppear:(BOOL)animated 
{ 
    NSLog (@"viewControllers %@",self.navigationController.viewControllers); 

    [super viewWillAppear:animated]; 
    if (self.p_userID) { 
     [self performSegueWithIdentifier: @"ConfirmID" sender: self]; 
     self.p_userID = nil; 
    } 
} 

(這performSegue應該只有當你設置self.p_userID而你B中仍然發生)

的鍵入的用戶ID邏輯更簡單。再次檢查患者ID。如果不存在,請在A中提醒(再次,您不需要顯示選項,因爲所有導航選項均可在沒有提示的情況下使用)。如果它在那裏,將self.p_userID設置爲該ID並啓動segue。

prepareForSegue您應該執行查找操作,將self.p_userID中的userInfo字典傳遞給C,然後將self.p_userID設置爲nil。或者(更好)只需將self.p_userID傳遞給C並在C中執行查找(假設您有單獨的模型源對象)。無論你做什麼,當你離開A時,一定要設置self.p_userID爲零,這樣你就不會自動觸發你不想要的繼續!也許在'viewWillDisappear'中將其歸零。

+0

謝謝!是的,我意識到,因爲我使用push segues,所以我應該只使用第一行!我更新了我的原始問題以反映這一點。然而,即使在這些變化導航欄仍然搞砸了,第二次到B的segue不完成等等。顯然我仍然失去了一些東西.... – PeterD

+0

@ user1959008 - 我看不到任何其他問題你已經發布的代碼 - 也許你可以用更多的代碼或信息來更新你的問題,確切地說沒有發生什麼事情或出錯。你是什​​麼意思'導航欄仍然搞砸了','繼續B到B沒有完成'......也許你的故事板上還有它的連接圖片。 – foundry

+0

他是,謝謝你,我更新了我的原始問題,導致屏幕截圖導致不良行爲,還有我的故事板截圖。 – PeterD