viewWillAppear,viewDidAppear没有被调用,没有发射

(这既是问题又是答案,因为需要相当多的挖掘才能find真正的答案。)

症状: viewWillAppearviewDidAppear没有在我的UIViewController中被调用。

原因:在UIViewControllerembeddedUINavigationControllerUITabBarController (我的情况)以某种方式中断调用这些方法。

解决scheme:在包含上述UINavigationController / UITabBarControllerUIViewController中手动调用它们。

例如(假设projectNavigationController是你的UINavigationController ):

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

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

 - (void)viewDidAppear:(BOOL)animated { 
     [超级viewDidAppear:animation];
     [projectNavigationController viewDidAppear:animated];
 }

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

在我的情况下,我有一个内部的UITabBarController ,我相应地调用了方法,所有都解决了。

(解决scheme归因: http : //davidebenini.it/2009/01/03/viewwillappear-not-being-called-inside-a-uinavigationcontroller/ )

我将继续前进,不同意@St3fan,并使用UIKit作为反例。

然而,一般embedded控制器的智慧(或缺乏)应该遵循健全的UIdevise原则。

最简单的反例是UITabBarControllersembedded的UINavigationControllers 。 这些都出现在各地。 就在我头顶,iPhone上的iPod应用程序和iPhone上的电话应用程序中的联系人。

我很好奇,想查看它们对视图的处理方式(添加到“超级控制器”视图或UIWindow ,我确信我会发现子控制器视图是超级用户的后代,控制器的视图,这是违背了St3fan的build议。

我掀起了一个非常快速的iPhone应用程序挂钩在InterfaceBuilder中的一切,以创build一个基于UITabBarController的应用程序与两个选项卡,其中第一个是一个简单的UIViewController UINavigationController ,因为它的根视图控制器,第二个选项卡与普通的旧UIViewController只是所以我有第二个标签稍后点击。

撒上一些NSLog语句来输出我们看到的控制器的各种UIView's

 tabBarController.view = <UILayoutContainerView: 0x5b0dc80; ... navigationController.view = <UILayoutContainerView: 0x59469a0; ... rootViewController.view = <UIView: 0x594bb70; ... Superview: <UIViewControllerWrapperView: 0x594cc90; ... Superview: <UINavigationTransitionView: 0x594a420; ... Superview: <UILayoutContainerView: 0x59469a0; ... // navigationController.view Superview: <UIViewControllerWrapperView: 0x594b430; ... Superview: <UITransitionView: 0x5b0e110; ... Superview: <UILayoutContainerView: 0x5b0dc80; ... // tabBarController.view Superview: <UIWindow: 0x5942a30; ... 

以“Superview”为前缀的行是rootViewController.view's视图链直到击中nil的输出。

然后当然快速浏览一下viewDidDisappear将在根视图控制器上viewDidDisappear的几个地方的调用栈。

首先,在根控制器上viewDidDisappear时的调用堆栈,作为新控制器被推入堆栈的结果:

 -[RootController viewDidDisappear:] -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:] ... 

其次,在最上面的UITabBarController中select另一个选项卡时调用堆栈:

 -[RootController viewDidDisappear:] -[UINavigationController viewDidDisappear:] -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:] 

所以在所有情况下,苹果公司似乎决定控制器应该在其embedded式子控制器上调用各种viewDidAppear等方法,并且应该类似地embedded视图。 我认为如果我们把UIKitdevise作为一个很好的领导者,那么OP就会把这个钉在头上。

我刚刚看到这种情况。 早些时候,由表格单元格select触发的界面构build器segue已经停止工作,并且在一些恼怒之后深入挖掘代码,我只是手动设置它,从表格视图委托中的单元格select覆盖调用。

后来,我在被调用的视图控制器中做了一些布局改变,并看到viewDidAppear没有被调用,如上所述。 debugging输出引用了“嵌套推送操作”或其他内容,因为在我的手动推送操作中我对自己有很大的评论

#warning I SHOULD NOT HAVE TO DO THIS!!

我突破了segue代码,果然,IB segue现在正在工作,这是我在表格单元格select代码中的手动操作,搞乱了被调用视图中的委托调用。 我删除了手动代码,一切都很好。

在推送视图后调用单元格select代码似乎很奇怪。 我必须做一个协议和委托获取调用者中选定单元格的索引path。