![](/img/trans.png)
[英]viewWillAppear, viewDidAppear and viewWillDisappear not being called on iOS 5 when using setViewControllers
[英]When using a UINavigationController the viewWillAppear or viewDidAppear methods of my controller are not called
這里是球場。
viewWillAppear
和viewDidAppear
可能不會被調用。我應該怎么做才能確保無論我的視圖層次結構如何都始終調用這兩個方法?
“復雜”視圖層次結構的示例:
UIViewController subclass containing a UITabBarController
|_ Each tab containing a UINavigationViewController
|_ Each UINavigationController controller containing a custom UIViewController
當您將 TabBarController 作為模式視圖呈現時,將調用 TabBarController 的viewWillAppear
和viewDidAppear
方法,但不會調用嵌套在 UINavigationViewControllers 下的自定義 UIViewControllers 的方法。
注意:這是在 2013 年編寫的。如今對 iOS 處理視圖層次結構方式的更改可能會使此解決方案變得無用和/或危險。 所以使用風險自負。
原始答案當在 UINavigationController 下嵌套自定義 UIViewController 時,可能不會調用自定義 viewController 的 viewWillAppear 和 viewDidAppear 方法,具體取決於您的視圖控制器層次結構的復雜性(想想模態視圖、選項卡視圖控制器內的導航控制器......)。 因此,如果您發現自己處於這種情況,您可以做些什么來確保調用這兩個方法?
答案...
這是一種非常優雅的實現方法,因為它不依賴於有關導航控制器何時加載控制器的任何假設。
有兩種方法可用:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
以下是代碼將如何更改。
你需要聲明你的 CustomViewController 實現了 UINavigationControllerDelegate 協議:
@interface CustomViewController : UIViewController <UINavigationControllerDelegate>
您需要將 CustomViewController 設置為初始化它的 UINavigationController 的委托。
最后,您還必須將 UINavigationControllerDelegate 方法的自定義實現添加到您的 CustomViewController 類實現中。 例如,您可以實現navigationController:willShowViewController:animated:
方法,以便:
項目清單
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([viewController isEqual:self]) {
[viewController viewWillAppear:animated];
} else if ([viewController conformsToProtocol:@protocol(UINavigationControllerDelegate)]){
// Set the navigation controller delegate to the passed-in view controller and call the UINavigationViewControllerDelegate method on the new delegate.
[navigationController setDelegate:(id<UINavigationControllerDelegate>)viewController];
[[navigationController delegate] navigationController:navigationController willShowViewController:viewController animated:YES];
}
}
而navigationController:didShowViewController:animated:
可以簡單地實現如下:
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
if ([viewController isEqual:self]) {
[self viewDidAppear:animated];
}
}
這種方法的好處實際上是您完全依賴 UINavigationViewController 應該工作的方式,並且您可以在正確的時間進行調用。 它還允許您在調用 viewWillAppear 方法之前在導航控制器層次結構中上下移動時傳遞委托。
同樣對於簡單的層次結構,這可能不是必需的。 但是,如果您發現自己的viewWillAppear
和viewDidAppear
方法未被調用,那么您現在知道該怎么做...
發生這種情況的一個原因是,如果您在UINavigationController
子類中覆蓋viewDidAppear:
並且不調用[super viewDidAppear:animated];
...
現在是 2015 年,您可能不需要像接受的答案那樣使用 UINavigationControllerDelegate 方法。 如果您有任何拼寫錯誤或復制/粘貼錯誤,請仔細檢查您的代碼。
我最近遇到了一個問題,即在某些復制/粘貼后不再調用viewDidAppear
。 閱讀@Yar 的回答后,我在我的代碼中對viewDidAppear
進行了搜索,發現[super viewDidAppear:animated];
在viewWillAppear
被錯誤調用:
-(void)viewWillAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//... ^^^
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// this is never called :(
}
只需在此處分享此發現,以防人們遇到相同的問題。
上述解決方案對我不起作用。 我的情況是嵌套在復雜 UINavigationController 下的自定義視圖控制器不會被稱為 viewWillAppear 和 viewDidAppear。 在自定義視圖控制器中使用以下內容:
beginAppearanceTransition(true, animated: animated) // Tells a child controller its appearance is about to change. Do not invoke viewWillAppear(_:), viewWillDisappear(_:), viewDidAppear(_:), or viewDidDisappear(_:) directly.
endAppearanceTransition() // Tells a child controller its appearance has changed.
我的問題僅與此類似。
CustomTabBarController -> CustomUINavigationController -> RootViewcontroller
除非您切換到另一個選項卡並返回,否則不會調用 CustomUINavigationController 和 RootViewController 的 viewWillAppear。
解決方法是調用 super.viewWillAppear(animated: true)
override func viewWillAppear(_ animated: Bool) {
**super.viewWillAppear(true)**
}
為了這個小錯誤,我掙扎了一天多。
應按如下方式進行:
見 (*1) 編輯
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CustomViewController *controller = [[CustomViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
[controller release];
self.window.rootViewController = navController; //(*1)
[self.window makeKeyAndVisible];
[navController release];
return YES;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.