使用 UINavigationController 时,不会调用我的控制器的 viewWillAppear 或 viewDidAppear 方法
这是球场。
- 我有一个 UIViewController 子类,它在 viewWillAppear 和 viewDidAppear 方法中执行某些操作。
- 我想将此视图控制器嵌套在 UINavigationViewController 中。
- 根据视图层次结构的复杂性,控制器的两个方法
viewWillAppear
和viewDidAppear
可能不会被调用。
那么我应该怎么做才能确保无论我的视图层次结构如何都始终调用这两个方法?
“复杂”视图层次结构的示例:
UIViewController subclass containing a UITabBarController
|_ Each tab containing a UINavigationViewController
|_ Each UINavigationController controller containing a custom UIViewController
当您将 TabBarController 作为模态视图呈现时,将调用 TabBarController 的 viewWillAppear 和 viewDidAppear 方法,但不会调用嵌套的自定义 UIViewController 的方法在 UINavigationViewControllers 下。
Here is the pitch.
- I have a UIViewController subclass which does something in its viewWillAppear and viewDidAppear methods.
- I want to nest this view controller in a UINavigationViewController.
- Depending on the view hierarchy complexity the two methods
viewWillAppear
andviewDidAppear
of my controller may not be called.
What should I do then to make sure these two methods are always called regardless of my view hierarchy?
Example of a "complex" view hierarchy:
UIViewController subclass containing a UITabBarController
|_ Each tab containing a UINavigationViewController
|_ Each UINavigationController controller containing a custom UIViewController
When you present the TabBarController as a modal view the viewWillAppear
and viewDidAppear
methods of the TabBarController are called but not those of the custom UIViewControllers nested under the UINavigationViewControllers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
注意:这是在 2013 年编写的。如今 iOS 处理视图层次结构方式的更改可能会使该解决方案变得无用和/或危险。因此,使用时请自行承担风险。
原始答案
当在 UINavigationController 下嵌套自定义 UIViewController 时,可能不会调用自定义 viewController 的 viewWillAppear 和 viewDidAppear 方法,具体取决于视图控制器层次结构的复杂性(想想模式视图、选项卡视图控制器内的导航控制器...)。那么,如果您发现自己处于这种情况,您可以做什么来确保调用这两个方法呢?
答案...
使用 UINavigationControllerDelegate 方法
这是一个非常优雅的实现方法,因为它不依赖于任何有关导航控制器何时加载控制器的假设。
有两种方法可用:
以下是代码的更改方式。
您需要声明您的 CustomViewController 实现 UINavigationControllerDelegate 协议:
您需要将 CustomViewController 设置为初始化它的 UINavigationController 的委托。
最后,您还必须将 UINavigationControllerDelegate 方法的自定义实现添加到 CustomViewController 类实现中。例如,您可以实现 navigationController:willShowViewController:animated: 方法,以便:
列表项
和
navigationController:didShowViewController:animated:
可以简单地实现如下:这种方法的好处实际上是您只依赖于 UINavigationViewController 应该工作的方式,并且您只需进行调用在正确的时间。它还允许您在调用 viewWillAppear 方法之前在导航控制器层次结构中上下移动时传递委托。
同样,对于简单的层次结构,这可能不是必需的。但是,如果您发现自己处于
viewWillAppear
和viewDidAppear
方法未被调用的情况,那么您现在知道该怎么做了......NOTE: this was written in 2013. Changes to the way iOS handles view hierarchies nowadays may render this solution useless and/or dangerous. So use at your own risk.
Original Answer
When nesting a custom UIViewController under a UINavigationController the methods viewWillAppear and viewDidAppear of the custom viewController may not be called depending on the complexity of your view controller hierarchy (think modal views, navigation controller inside tab view controller...). So if you find yourself in this situation what can you do to ensure these two methods are called?
The answer...
Use the UINavigationControllerDelegate methods
This is a very elegant method to implement for it does not rely on any assumptions regarding when the controller will be loaded by the navigation controller.
There are two methods available:
Here is how the code would change.
You need to declare that your CustomViewController implements the UINavigationControllerDelegate protocol:
You need to set your CustomViewController as the delegate of the UINavigationController where you initialize it.
Last you must also add your custom implementation of the UINavigationControllerDelegate methods to your CustomViewController class implementation. For instance you can implement the
navigationController:willShowViewController:animated:
method so that:List item
And the
navigationController:didShowViewController:animated:
can be implemented simply as follows:The benefit of this approach is really that you solely rely on the way the UINavigationViewController is supposed to work and you make your calls just at the right time. It also allows you to pass the delegation around as you move up and down the navigation controller hierarchy right before the viewWillAppear method is called.
Again for simple hierarchy this may not be required. But if you ever find yourself in a situation where your
viewWillAppear
andviewDidAppear
methods are not called you now know what to do...发生这种情况的原因之一是,如果您在
UINavigationController
子类中重写viewDidAppear:
并且不调用[super viewDidAppear:animated];
.. 。One reason this will happen is if you override
viewDidAppear:
in yourUINavigationController
subclass and don't call[super viewDidAppear:animated];
...现在是 2015 年,您可能不需要像接受的答案中那样使用 UINavigationControllerDelegate 方法。如果您有任何拼写错误或复制/粘贴错误,请仔细检查您的代码。
我最近遇到了一个问题,即在复制/粘贴后不再调用
viewDidAppear
。阅读@Yar的回答后,我在代码中搜索了viewDidAppear
,发现[super viewDidAppear:animated];
在viewWillAppear
中被错误地调用>:请在此分享此发现,以防人们遇到同样的问题。
It is 2015 now and you probably don't need to use the UINavigationControllerDelegate methods as in the accepted answer. Just check carefully your code if you have any typo or copy/paste error.
I ran into an issue lately that
viewDidAppear
is no longer called after some copy/paste. After reading @Yar's answer, I did a search onviewDidAppear
in my code and found that[super viewDidAppear:animated];
was mistakenly called inviewWillAppear
:Just share this finding here in case people run into same issue.
应该按如下方式完成:
请参阅(*1)编辑
it should be done as follows:
See (*1) edit
上述解决方案对我不起作用。我的情况是嵌套在复杂的 UINavigationController 下的自定义视图控制器不被称为 viewWillAppear 和 viewDidAppear。在自定义视图控制器中使用以下内容:
The above solution not works for me. My case is the custom view controller nested under a complex UINavigationController not gets called viewWillAppear and viewDidAppear. Use below in custom view controller:
我的问题仅与此类似。
自定义TabBarController ->自定义UINavigationController -> CustomUINavigationController 和 RootViewController 的RootViewcontroller
viewWillAppear 不会被调用,除非您切换到另一个选项卡并返回。
解决方案是调用 super.viewWillAppear(animated: true)
我为这个小错误奋斗了一天多。
My problem was similar to this only.
CustomTabBarController -> CustomUINavigationController -> RootViewcontroller
viewWillAppear of CustomUINavigationController and RootViewController are not getting called unless you switched to another tab and come back.
The solution is call super.viewWillAppear(animated: true)
I struggled for more than a day for this small mistake.