从弹出的 UINavigationController 或 UITabBarController 确定 viewWillAppear
Posted
技术标签:
【中文标题】从弹出的 UINavigationController 或 UITabBarController 确定 viewWillAppear【英文标题】:Determine viewWillAppear from Popped UINavigationController or UITabBarController 【发布时间】:2015-10-09 01:41:27 【问题描述】:我无法找到一种方法来区分从导航控制器堆栈弹出和从 UITabBarController 进入视图控制器。
我只想在视图从 TabBar 呈现时调用 ViewWillAppear 中的方法,而不是当有人在导航控制器中按回时调用。
如果我不使用 TabBarController,我可以使用 viewDidLoad 轻松获得此功能。
我试过了,
override func viewWillAppear(animated: Bool)
super.viewWillAppear(animated)
println("View Will Appear")
if isBeingPresented()
println("BP")
if isMovingFromParentViewController()
println("from")
if isMovingToParentViewController()
println("to")
但是当我按下 Tab 按钮或按下返回按钮时没有区别。
只有“视图会出现”被调用。
使用 ios 8.4 / Swift
【问题讨论】:
您是否尝试添加一些观察者并使用 NSNotificationCenter ? 没想到 - 会考虑 您的 ViewController 堆栈看起来如何?您的视图控制器是否始终包含在导航控制器中(作为根视图控制器或推送视图控制器)? 是的,UITabBarController,4 个选项卡,每个选项卡都包含 UINavControllers(具有向下钻取的 UITableViewControllers) 【参考方案1】:听起来UITabBarControllerDelegate
很好用。
首先,在您的 ViewController comingFromTab
上添加一个 Bool
属性:
class MyViewController: UIViewController
var comingFromTab = false
// ...
将您的UITabBarControllerDelegate
设置为您想要的任何类并实现方法shouldSelectViewController
。您可能还想继承 UITabBarController 并将它们放在那里。
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool
if let myViewController = viewController as? MyViewController
myViewController.comingFromTab = true
如果您的选项卡的初始视图控制器是 UINavigationController
,则您必须打开它并访问它的第一个视图控制器:
if let navController = viewController as? UINavigationController
if let myViewController = navController.viewControllers[0] as? MyViewController
// do stuff
最后,在视图控制器的viewWillAppear
中添加您需要的任何功能:
override func viewDidAppear(animated: Bool)
super.viewDidAppear(animated)
// ...
if comingFromTab
// Do whatever you need to do here if coming from the tab selection
comingFromTab = false
【讨论】:
我不得不将comingFromTab = false 反转为true,因为在第一次加载时,它在第一次选择该选项卡时不起作用。交换它,使其工作100%。我不想使用 TabBarDelegate,但似乎这是唯一的方法。【参考方案2】:您可以查看parentViewController
属性
override func viewWillAppear(animated: Bool)
super.viewWillAppear(animated)
if parentViewController is UITabBarController
// Presented by UITabBarController
else if parentViewController is UINavigationController
// Presented by UINavigationController
else
// Presented by ...
【讨论】:
不起作用 - 由 UITabBarController 呈现的永远不会被调用。当我选择我的选项卡时,或者当我回到导航控制器堆栈时。只有 UINavigationController 被调用,并且在两种情况下都被调用。 你有什么结构?我在想这样的事情:UITabBarController 一页带有自定义 vc,另一页带有 UINavigationController 可能会推送相同的自定义 vc 是的,UITabBarController,4个标签,每个标签包含UINavControllers【参考方案3】:没有办法确定。所以我想最简单的方法是添加一些变量,您必须在弹出回该视图控制器并在 viewWillAppear 中检查它的状态之前对其进行更改。
class YourViewController: UIViewController
var poppingBack = false
override func viewWillAppear(animated: Bool)
super.viewWillAppear(animated)
if !poppingBack
// your logic
else
poppingBack = false // reset it for next time
// somewhere else in code, suppose yourVC is YourViewController
yourVC.poppingBack = true
self.navigationController.popToViewController(yourVC, animated: true)
您也可以尝试实现UINavigationControllerDelegate
的- navigationController:willShowViewController:animated:
方法,并检查在从标签栏显示您的视图控制器时是否会调用它。
【讨论】:
以上是关于从弹出的 UINavigationController 或 UITabBarController 确定 viewWillAppear的主要内容,如果未能解决你的问题,请参考以下文章