【问题标题】:viewWillAppear, viewDidAppear not being called, not firingviewWillAppear,viewDidAppear 没有被调用,没有触发
【发布时间】:2011-04-03 09:43:40
【问题描述】:

(这既是问题又是答案,因为需要大量挖掘才能找到真正的答案。)

症状:viewWillAppear、viewDidAppear 没有在我的 UIViewController 中被调用。

原因:在 UIViewController 中嵌入 UINavigationController 或 UITabBarController(我的情况)会以某种方式中断这些方法的调用。

解决方案:在包含上述UINavigationController / UITabBarController 的UIViewController 中手动调用它们。

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

-(void)viewWillAppear:(BOOL)动画{ [超级viewWillAppear:动画]; [projectNavigationController viewWillAppear:animated]; } -(void)viewWillDisappear:(BOOL)动画{ [超级viewWillDisappear:动画]; [projectNavigationController viewWillDisappear:animated]; } -(void)viewDidAppear:(BOOL)动画{ [超级 viewDidAppear:动画]; [projectNavigationController viewDidAppear:animated]; } -(无效)viewDidDisappear:(BOOL)动画{ [超级 viewDidDisappear:动画]; [projectNavigationController viewDidDisappear:animated]; }

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

(解决方案的归属:http://davidebenini.it/2009/01/03/viewwillappear-not-being-called-inside-a-uinavigationcontroller/)

【问题讨论】:

  • 只是因为我很好奇...:为什么要将标签栏控制器包装到另一个视图控制器中? :) 在大多数情况下,它们是视图(控制器)层次结构的根...
  • +1 .. 真的解决了我的问题.. 干杯

标签: iphone objective-c uitabbarcontroller viewwillappear


【解决方案1】:

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

然而,嵌入控制器的智慧(或缺乏智慧)通常应该以健全的 UI 设计原则为指导。

最简单的反例是嵌入在UITabBarControllers 中的UINavigationControllers。这些无处不在。就在我的脑海中,iPhone 上的 iPod 应用程序和 iPhone 上电话应用程序中的联系人。

我很好奇,懒得去检查他们对视图做了什么(添加到“超级控制器”视图或UIWindow。我很确定我会发现子控制器视图是视图层次结构中超级控制器视图的后代,这与 St3fan 的建议相反。

我创建了一个非常快速的 iPhone 应用程序,将所有内容都连接到 InterfaceBuilder 中,以创建一个带有两个选项卡的基于 UITabBarController 的应用程序,其中第一个是 UINavigationController,带有一个普通的 ole UIViewController 作为它的根视图控制器,和一个带有普通旧 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 superview 链向上直到达到 nil 的输出。

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

首先,在根控制器上调用 viewDidDisappear 时的调用堆栈,因为新控制器被压入堆栈:

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

二、在最顶层的UITabBarController中选择另一个tab时的调用栈:

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

因此,在所有情况下,Apple 似乎都决定控制器应该在其嵌入式子控制器上调用各种viewDidAppear 等方法,并且应该以类似方式嵌入视图。我认为如果我们要将UIKit 设计作为一个很好的线索,那么 OP 就在头上一针见血。

【讨论】:

  • 有趣的分析 imaginaryboy。我很欣赏你的 POV St3fan。在典型的设置中,UITabBarController(它有自己的导航控制器和视图控制器)被添加到窗口中。很容易看到这一点。然而,我的情况略有不同。在我的情况下,用户通过模式进入应用程序的特定模式。在另一种模式下,用户最初看到的 UITabBarController 是不同的。也许我可以调用应用程序委托将新的 UITabBarcontroller 添加到窗口(?),但将其添加到模态 UIViewController 更容易。
【解决方案2】:

我刚刚看到了同样的情况。早些时候,由表格单元格选择触发的界面构建器 segue 已经停止工作,在对代码进行了一些恼怒之后,我只是手动设置它,从表格视图委托中的单元格选择覆盖调用。

后来我在被调用的视图控制器中进行了一些布局更改,发现 viewDidAppear 没有被调用,如上所述。调试输出提到了“嵌套推送操作”之类的东西,因为我在手动推送操作中对自己有很大的评论

#warning I SHOULD NOT HAVE TO DO THIS!!

我对 segue 代码设置了断点,果然,IB segue 现在正在工作,是我在表格单元格选择代码中的手动操作弄乱了被调用视图中的委托调用。我删除了手动代码,一切又好了。

在推送视图后调用单元格选择代码似乎很奇怪。我必须做一个协议并委托来获取调用者中所选单元格的索引路径。

【讨论】:

    猜你喜欢
    • 2011-05-19
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 2016-03-24
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    相关资源
    最近更新 更多