22

我目前需要實現一些代碼,當從我的導航控制器彈出頂視圖控制器。有沒有辦法檢測視圖控制器何時從導航控制器堆棧彈出?如何檢測瀏覽控制器是否從導航控制器彈出?

儘可能我想,因爲我在我的項目使用splitview,並選擇不同的行中的主視圖也將觸發viewWillDisappear/viewDidDisappear方法使用viewWillDisappearviewDidDisappear望而卻步。

+0

爲什麼不使用導航控制器的委託方法? – matt

+2

您仍然可以使用viewWillDissapear/viewDidDisappear並查明viewcontroller是否真的彈出。這可能有所幫助:http://stackoverflow.com/questions/1816614/viewwilldisappear-determine-whether-view-controller-is-being-popped-or-is-showi – Niraj

回答

20

UPDATE 20150430

基於phatmann的反饋(下面的第一個評論),我很好奇,如果有什麼東西改變,因爲我的回答在一年前這個問題。我編寫了一個簡單的示例應用程序,並獲得了一些有趣的結果。

選項1,例如

https://github.com/greymouser/TestNVC

我沒有能夠輕鬆測試前8.x的能力,所以我不知道如果從那時開始,事情已經改變。然而,我最初描述的行爲仍然發生。 但是,由於將測試應用程序放在一起,我確實注意到我以前從未有過的奇怪之處。

如果我只是依靠{will,did}MoveToParentViewController,我發現一個虛假的didMoveToParentViewController:調用時推薦rootVC上的第一個非rootVC,父母!= nil(暗示它被添加,不被刪除)。在我的原始答案時間周圍,我沒有遇到這種情況,因爲我通常在我的NVC上擁有「永久性」rootVC,並且沒有在那裏實施回調。請參閱日誌設置爲LOG_WILL_DID_MTPVC(在ViewController.m中)的示例應用程序。這是一個 - 編輯的空間 - 快照的我所看到的:單獨使用{will,did}MoveToParentViewController

TestNVC[] -[vc(rootVC) willMoveToParentViewController [entering] 
TestNVC[] -[vc(rootVC) didMoveToParentViewController [entering] 
TestNVC[] -[vc(1) willMoveToParentViewController [entering] 
TestNVC[] -[vc(rootVC) didMoveToParentViewController [entering] # <-- this is odd 
TestNVC[] -[vc(1) didMoveToParentViewController [entering] 
... 

我原來的答覆建議,因爲它是一個「一站式」處理這種行爲。然而,現在我已經看到了rootVC的虛假呼叫,我建議混合使用{will,did}MoveToParentViewController以及標準UINavigationControllerDelegate回調。對於示例應用程序中的這種行爲,請將日誌記錄設置爲LOG_WILL_DID_MTPVC_LEAVING_AND_NVC_WILL_DID_SHOW_VC。現在我們看到以下內容:

TestNVC[] -[nvcD willShowViewController]: rootVC 
TestNVC[] -[nvcD didShowViewController]: rootVC 
TestNVC[] -[nvcD willShowViewController]: 1 
TestNVC[] -[nvcD didShowViewController]: 1 
TestNVC[] -[nvcD willShowViewController]: 2 
TestNVC[] -[nvcD didShowViewController]: 2 
TestNVC[] -[vc(2) willMoveToParentViewController [leaving] 
TestNVC[] -[nvcD willShowViewController]: 1 
TestNVC[] -[vc(2) didMoveToParentViewController [leaving] 
TestNVC[] -[nvcD didShowViewController]: 1 
TestNVC[] -[vc(1) willMoveToParentViewController [leaving] 
TestNVC[] -[nvcD willShowViewController]: rootVC 
TestNVC[] -[vc(1) didMoveToParentViewController [leaving] 
TestNVC[] -[nvcD didShowViewController]: rootVC 

......現在這更有意義了。

選項2

正在使用您的雷士sublcass,覆蓋- pushViewController:animated:- popViewControllerAnimated:,並應用要在VC任何行爲我沒有探索另一種選擇推,或從返回的VC流行。 (一定要記得打電話super在你重寫,如果你嘗試這個。)

更新彙總

所以,感謝phatmann用於爲改變這一機會。我想我的回答是更多現在正確。但是,我不太確定它是否「完全不真實」。;-)

ORIGINAL

如果您所描述的確切行爲是你在找什麼,然後覆蓋你的孩子視圖控制器在以下方面:

- (void)willMoveToParentViewController:(UIViewController *)parent; 
- (void)didMoveToParentViewController:(UIViewController *)parent; 

willMoveToParentViewController:將調用與父母!=輸入時爲零,並且在離開時父母==零。 didMoveToParentViewController:將始終有父!=零。

有時,viewDidDisappear可能是有意義的。但是,如果您真的想從父容器視圖控制器中查找push和pop,那麼上面的這些方法就是您想要的。

+0

至少在iOS 8中,不會調用'willMoveToParentViewController'用於導航控制器中的子視圖控制器。當子視圖控制器最初放置在導航視圖控制器中時,除了在彈出時調用時,還會調用「didMoveToParentViewController」。所以這些方法對於OP所需要的是沒有用的。沒有選擇,只能downvote。 – phatmann

+0

@phatmann感謝您的反饋。我已經用示例應用程序和日誌記錄更新了我的答案。您的評論幫助我確定了我沒有注意到的與我的第一個答案有關的問題,但是,我認爲您的問題/要點也不是100%正確的。請參閱更新以獲取完整說明。乾杯! – greymouser

+0

哇,很好的研究,謝謝你這樣做。現在upvoted :-)但是,蘋果讓這些電話很奇怪,我會繼續避免它們。最好使用一個布爾值,就像那樣。 – phatmann

43

可以檢測是否一個視圖是使用isMovingFromParentViewController屬性視圖控制器被彈出,如下所示:

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
    if ([self isMovingFromParentViewController]) 
    { 
     NSLog(@"View controller was popped"); 
    } 
    else 
    { 
     NSLog(@"New view controller was pushed"); 
    } 
} 

isMovingFromParentViewController

返回一個布爾值,指示該視圖控制器在 被從其父母移除的過程。

+0

這應該是公認的答案 –

+0

@Nishant我明白,視圖消失時調用了MovingFromParentViewController,但視圖可以消失,因爲ViewController被推入或彈出。當viewController被推入導航堆棧時,或只有當它被固定時(例如後退按鈕),該方法isMovingFromParentViewController是否也被調用? – bibscy

+0

@bibscy'isMovingFromParentViewController'僅在視圖控制器被彈出而未被壓入時被調用。 –

相關問題