viewWillAppear,viewDidAppear不被调用,不触发 [英] viewWillAppear, viewDidAppear not being called, not firing
问题描述
(这既是问题又是答案,因为要花很多时间才能找到真正的答案.)
(This is both question and answer since it took quite a bit of digging to find the real answer.)
症状:viewWillAppear
,viewDidAppear
没有在我的UIViewController中被调用.
Symptom: viewWillAppear
, viewDidAppear
were not being called in my UIViewController.
原因:在UIViewController
中嵌入UINavigationController
或UITabBarController
(在我的情况下)以某种方式中断了这些方法的调用.
Cause: Embedding a UINavigationController
or UITabBarController
(my case) in a UIViewController
somehow interrupts with the calling of these methods.
解决方案:在包含上述UINavigationController
/UITabBarController
的UIViewController
中手动调用它们.
Solution: Call them manually in the UIViewController
that contains the aforementioned UINavigationController
/ UITabBarController
.
例如(假设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 {
[super viewDidAppear:animated];
[projectNavigationController viewDidAppear:animated];
}
-(void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[projectNavigationController viewDidDisappear:animated];
}
在我的情况下,我有一个内部UITabBarController
,我相应地调用了方法,所有问题都解决了.
In my case I had an inner UITabBarController
and I called the methods accordingly and all was solved.
(解决方案的出处: http ://davidebenini.it/2009/01/03/viewwillappear-not-being-call-inside-a-uinavigationcontroller/)
推荐答案
我将继续反对@ St3fan,并使用UIKit
作为反例.
I'm going to go ahead and disagree with @St3fan, and use UIKit
as the counter-example.
但是,一般来说,嵌入控制器的智慧(或缺乏智慧)应遵循理智的UI设计原则.
However, the wisdom (or lack thereof), of embedding controllers in general should be guided by sane UI design principles.
最简单的反例是UITabBarControllers
中嵌入的UINavigationControllers
.这些出现在各处. iPhone上的iPod应用程序和iPhone上的Phone应用程序中的通讯录就在我头上.
The easiest counter-example is UINavigationControllers
embedded in UITabBarControllers
. These appear all over the place. Just off the top of my head, the iPod app on iPhone, and Contacts within the Phone app on iPhone.
我很好奇,想检查一下它们对视图的作用(添加到超级控制器"视图或UIWindow
中.)我很确定自己会发现子控制器视图是视图层次结构中超级控制器视图的后代,这与St3fan的建议相反.
I was curious enough to bother to check what they do with the views (add to the "super-controller" view or to the UIWindow
. I was pretty sure I was going to find that the sub-controller views were descendants of the super-controller views in the view hierarchy, which is contrary to St3fan's recommendation.
我用一个非常快速的iPhone应用程序将所有内容挂接到InterfaceBuilder中,以创建一个基于UITabBarController
的应用程序,该应用程序有两个选项卡,第一个选项卡是UINavigationController
,带有普通OLE UIViewController
作为其根视图控制器,还有一个带有普通旧UIViewController
的第二个标签,只是我有一个第二个标签可在以后单击.
I whipped up a very quick iPhone app hooking everything up in InterfaceBuilder to create a UITabBarController
based app with two tabs, the first of which was a UINavigationController
with a plain ole UIViewController
as it's root view controller, and a 2nd tab with a plain old UIViewController
just so I had a 2nd tab to click later.
添加一些NSLog
语句,以输出用于控制器的各种UIView's
:
Sprinkle in some NSLog
statements to output the various UIView's
for the controllers we see this:
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链上走到零为止的输出.
The lines prefixed with "Superview" were the output from walking up the rootViewController.view's
superview chain until hitting nil.
然后当然可以快速浏览一下在根视图控制器上将调用viewDidDisappear
的几个地方的调用堆栈.
Then of course a quick glance at the call stack in a couple of places where viewDidDisappear
would get called on the root view controller.
首先,由于将新控制器压入堆栈而导致在根控制器上调用viewDidDisappear
时的调用堆栈:
First, the call stack when viewDidDisappear
is called on the root controller as a result of a new controller being pushed on to the stack:
-[RootController viewDidDisappear:]
-[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:]
...
第二,在最顶部的UITabBarController中选择另一个选项卡时,调用堆栈:
Second, the call stack when another tab is selected in the top-most UITabBarController:
-[RootController viewDidDisappear:]
-[UINavigationController viewDidDisappear:]
-[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:]
因此,在所有情况下,苹果似乎都决定控制器应在其嵌入式子控制器上调用各种viewDidAppear
等方法,并且视图应类似地进行嵌入式.我认为,如果我们要采用UIKit
设计作为遵循的很好的指导,那么OP就打在了这个头上.
So in all cases, it seems that Apple decided that controllers should be calling the various viewDidAppear
, etc methods on their embedded subcontrollers and that the view's should be embedded similarly. I think the OP hit this nail right on the head if we're to take UIKit
design as a good lead to follow.
这篇关于viewWillAppear,viewDidAppear不被调用,不触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!