在我的应用程序中,我有大约十几个不同的视图控制器,它们以不同的顺序被推入堆栈或从堆栈中弹出。当视图出现时(我正在使用viewDidAppear
方法),我需要确定这是因为该视图刚刚被推入堆栈还是因为它的子视图之一从堆栈中弹出。
我经历了这个问题:viewWillDisappear:确定视图控制器是被弹出还是显示子视图控制器
但我认为这对我帮助不大。请问有什么建议吗?
在我的应用程序中,我有大约十几个不同的视图控制器,它们以不同的顺序被推入堆栈或从堆栈中弹出。当视图出现时(我正在使用viewDidAppear
方法),我需要确定这是因为该视图刚刚被推入堆栈还是因为它的子视图之一从堆栈中弹出。
我经历了这个问题:viewWillDisappear:确定视图控制器是被弹出还是显示子视图控制器
但我认为这对我帮助不大。请问有什么建议吗?
如果您可以管理它,最好的解决方案是尝试修改您的代码,以便无论控制器只是被推送还是它的孩子刚刚被弹出都无关紧要。从根本上说,视图控制器在其视图和应用程序操作的数据之间进行调解。只要该数据是最新的,控制器就不应该关心在其视图出现之前发生的事情。您的控制器当前根据应用程序的先前状态执行的任务(例如更新数据)可能确实更好地位于不同的类中。
如果您使用情节提要,另一种可能性是依赖-prepareForSegue:sender:
而不是-viewDidAppear
. 您在该方法中传递的 segue 具有标识源视图控制器和目标视图控制器的属性,这通常足以告诉您您的控制器是如何成为当前控制器的。
如果这些都不适用于您的情况,请考虑将您的配置代码移动到一种或多种不同的方法。您面临的问题的根源在于,这-viewWillAppear
实际上并不意味着您需要它。创建一个确实意味着您需要的方法,例如-childControllerFinished
,并使用它来完成您需要的配置工作。
您可以做的是在您的视图控制器上有一个 BOOL 属性,称为 alreadyPushed 或类似的东西。然后在您的 viewDidAppear 方法中检查它是否为假(这将是第一次调用 viewDidAppear),是否将其设置为真。
然后,当弹出子视图 viewController 时,viewDidAppear 方法将检查是否已经将属性设置为 true,如果您知道子视图刚刚被弹出。
如果一个视图控制器被压入堆栈,它的viewDidLoad
方法将被调用;如果它的子控制器被弹出,则不viewDidLoad
被调用。
- (void)viewDidLoad {
[super viewDidLoad];
//do any setup you want to do only when the view is pushed onto the
//stack for the first time; this method will not be called
//when the view's subview is popped and this one becomes visible
}
因此,当第一次推送视图控制器时,使用viewDidLoad
(或initWithNibName
,取决于你在做什么)进行一次性设置,以及每次视图出现时viewDidAppear
你想要进行的设置。使用 UINavigationController,您可能希望在 UINavigationControllerDelegate 协议中实现这两个方法:
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
[viewController viewWillAppear:animated];
//do any every-time setup *before* the view is shown
}
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
[viewController viewDidAppear:animated];
//do any every-time setup *after* the view is shown
}