从弹出的 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的主要内容,如果未能解决你的问题,请参考以下文章

从弹出的视图控制器传递数据

如何从弹出的 Expo 项目中删除“android.hardware.location”权限请求?

如何从弹出的谷歌地图信息窗口中删除关闭按钮(x)边框?

Kivy - 从弹出窗口自动启动方法

Chrome浏览器页面中文显示乱码怎么办

win10能不能做到同时多个用户远程桌面登录