UIViewController viewDidAppear - 因为它被推送还是因为子视图被弹出?
在我的应用程序中,我有大约十几个不同的视图控制器,以不同的顺序推入堆栈或从堆栈中弹出。当一个视图出现时(我使用的是 viewDidAppear 方法),我需要确定这是因为该视图刚刚被推入堆栈还是因为它的子视图之一被从堆栈中弹出。
我经历过这个问题:viewWillDisappear:确定是否视图控制器正在弹出或正在显示子视图控制器
但我认为这对我没有多大帮助。请问有什么建议吗?
In my app, I have about a dozen different view controllers, pushed onto or popped from the stack in different orders. When a view has appeared (I'm using viewDidAppear
method) I need to determine whether this is because this view has just been pushed onto the stack or because one of its subviews was popped from the stack.
I went through this question: viewWillDisappear: Determine whether view controller is being popped or is showing a sub-view controller
But I don't think it's helping me very much. Any suggestions please?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您可以管理它,最好的解决方案是尝试修改您的代码,以便控制器是否刚刚被推送或其子级刚刚弹出都无关紧要。从根本上来说,视图控制器在其视图和应用程序操作的数据之间进行协调。只要该数据是最新的,控制器就不应该关心其视图出现之前发生的情况。您的控制器当前根据应用程序的先前状态执行的任务(例如更新数据)可能确实最好位于不同的类中。
如果您使用故事板,另一种可能性是依赖
-prepareForSegue:sender:
而不是-viewDidAppear
。您在该方法中传递的 Segue 具有标识源视图控制器和目标视图控制器的属性,这通常足以告诉您控制器如何成为当前控制器。如果这两种方法都不适合您的情况,请考虑将您的配置代码移至一种或多种不同的方法。您面临的问题的根源是
-viewWillAppear
实际上并不意味着您需要它。创建一个确实意味着您需要的方法,例如-childControllerFinished
,并使用that来完成您需要的配置工作。The best solution, if you can manage it, is to try to revise your code so that it doesn't matter whether the controller was just pushed or its child was just popped. Fundamentally, a view controller mediates between its view and the data that the app operates on. As long as that data is up to date, the controller shouldn't be concerned with what was happening before its view appeared. Tasks that your controller currently does based on the previous state of the app, such as updating the data, might really be better located in a different class.
Another possibility, if you're using storyboards, is to rely on
-prepareForSegue:sender:
instead of-viewDidAppear
. The segue you're passed in that method has properties that identify the source and destination view controllers, and that's usually enough information to tell you how your controller came to be the current one.If neither of those work in your case, consider moving your configuration code to one or more different methods. The root of the problem you're facing is that
-viewWillAppear
really doesn't mean what you need it to. Create a method that does mean what you need, like-childControllerFinished
, and use that to do the configuration work that you need.你可以做的就是在你的视图控制器上有一个 BOOL 属性,称为 hasPushed 或类似的东西。然后在 viewDidAppear 方法中检查它是否为 false(这将是第一次调用 viewDidAppear),如果将其设置为 true。
然后,当弹出子视图 viewController 时,viewDidAppear 方法将检查alreadyPushed 属性是否设置为 true,如果您知道子视图刚刚被弹出。
What you could do is have a BOOL property on your view controller, called alreadyPushed or something similar. Then in your viewDidAppear method check if it is false (Which it will be the first time the viewDidAppear is called), if it is set it to true.
Then when a subview viewController is popped the viewDidAppear method would check to see if the alreadyPushed property is set to true, if it is you know that a subview has just been popped.
如果视图控制器被压入堆栈,它的 viewDidLoad 方法将被调用;如果它的子控制器被弹出,则不会调用
viewDidLoad
。因此,当第一次推送视图控制器时,使用
viewDidLoad
(或initWithNibName
,具体取决于您在做什么)进行一次性设置,并且viewDidAppear
用于每次视图出现时您想要执行的设置。使用 UINavigationController,您可能希望在 UINavigationControllerDelegate 协议中实现这两个方法:If a view controller is pushed onto the stack, it's
viewDidLoad
method will be called; if it's sub-controller is popped, thenviewDidLoad
is NOT called.So, use
viewDidLoad
(orinitWithNibName
, depending on what you're doing) for one-time setup when the view controller is pushed for the first time, andviewDidAppear
for setup that you want to do every time the view appears. With the UINavigationController, you might want to implement these two methods in the UINavigationControllerDelegate protocol: