在我的應用程序中,我有大約十幾個不同的視圖控制器,以不同的順序壓入或彈出堆棧。當一個視圖出現時(我正在使用viewDidAppear
方法)我需要確定這是因爲這個視圖剛被推入堆棧還是因爲它的一個子視圖從堆棧中彈出。UIViewController viewDidAppear - 因爲它被推送或因爲子視圖被彈出?
但我不認爲這是幫助我非常多。有什麼建議嗎?
在我的應用程序中,我有大約十幾個不同的視圖控制器,以不同的順序壓入或彈出堆棧。當一個視圖出現時(我正在使用viewDidAppear
方法)我需要確定這是因爲這個視圖剛被推入堆棧還是因爲它的一個子視圖從堆棧中彈出。UIViewController viewDidAppear - 因爲它被推送或因爲子視圖被彈出?
但我不認爲這是幫助我非常多。有什麼建議嗎?
你可以做的是在你的視圖控制器上有一個BOOL屬性,叫做alreadyPushed或類似的東西。然後在viewDidAppear方法中檢查它是否爲false(它將是第一次調用viewDidAppear),如果它被設置爲true。
然後當一個子視圖viewController被彈出時,viewDidAppear方法會檢查看看alreadyPushed屬性是否設置爲true,如果是你知道子視圖剛剛被彈出。
如果一個視圖控制器被推入堆棧,它會調用viewDidLoad
方法;如果它的子控制器彈出,則不調用viewDidLoad
。
- (void)viewDidLoad {
[super viewDidLoad];
//do any setup you want to do only when the view is pushed onto the
//stack for the first time; this method will not be called
//when the view's subview is popped and this one becomes visible
}
因此,使用viewDidLoad
(或initWithNibName
,這取決於你在做什麼)的一次性設置,當視圖控制器被推爲第一時間,viewDidAppear
爲你想要做每一個設置時間視圖出現。隨着UINavigationController的,你可能想實現在UINavigationControllerDelegate協議這兩種方法:
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
[viewController viewWillAppear:animated];
//do any every-time setup *before* the view is shown
}
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
[viewController viewDidAppear:animated];
//do any every-time setup *after* the view is shown
}
假設每次將視圖控制器添加到導航堆棧時都會調用'-viewDidLoad',這是不安全的。視圖控制器可能在使用之前就已經被創建好了,並且在某種程度上它的視圖也可能被創建。這時'-viewDidLoad'將被調用。之後,視圖已經被加載,並且該方法不會僅僅因爲控制器被推入堆棧而被調用。 – Caleb 2011-12-21 16:26:17
非常好的一點。但是,這聽起來不像這裏的情況。 OP沒有提到任何有關視圖控制器預緩存的內容。 – 2011-12-21 16:38:45
@Caleb:這是一個很好的觀點,特別是對我而言。當視圖控制器被推入並彈出到堆棧上時,當我彈出一個控制器時,我不會銷燬它,但稍後當我需要再次推入時重用它。 – 2011-12-21 17:03:04
最好的解決辦法,如果你能管理它,是試圖修改你的代碼,這樣也無所謂是否控制器剛剛被推或其孩子剛剛彈出。從根本上說,視圖控制器在視圖和應用程序運行的數據之間進行調解。只要這些數據是最新的,控制者就不應該關注它出現之前發生的事情。您的控制器當前基於應用的以前狀態執行的任務(例如更新數據)可能確實位於不同類中。
如果您正在使用故事板,另一種可能性是依靠-prepareForSegue:sender:
而不是-viewDidAppear
。您在該方法中傳遞的segue具有標識源視圖控制器和目標視圖控制器的屬性,通常這些信息足以告訴您控制器如何成爲當前控制器。
如果這兩者都不起作用,請考慮將您的配置代碼移至一個或多個不同的方法。你面臨的問題的根源在於,-viewWillAppear
真的並不意味着你需要它。創建一個方法,確實的意思是你需要什麼,如-childControllerFinished
,並使用那來做你需要的配置工作。
謝謝,這似乎是最簡單的方法。 – 2011-12-21 17:03:21