从标签栏控制器模态显示视图

Posted

技术标签:

【中文标题】从标签栏控制器模态显示视图【英文标题】:Present a View modally from a tab bar controller 【发布时间】:2017-09-06 09:09:20 【问题描述】:

如何从标签栏控制器以模态方式呈现视图,以便视图覆盖实际视图?

我想用相机构建一个视图。就像“WhatsApp”或“Ins​​tagram”一样,中间有一个按钮,用户可以单击该按钮并显示相机视图。

此外,当点击关闭按钮时,用户应该移动他之前所在的选项卡。

这就是我的 ViewController 连接到 TabBarController 的方式:

【问题讨论】:

【参考方案1】:

我必须在我目前正在构建的应用程序中实现类似的东西,这相对简单,您需要实现 UITabBarController 的委托方法才能实现这一点。

你需要实现的委托方法是: tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool

从此方法返回 false 将阻止标签控制器选择您的标签,然后您只需要实现自己的逻辑以编程方式呈现 UIViewController

这是一个例子:

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool 

    // If your view controller is emedded in a UINavigationController you will need to check if it's a UINavigationController and check that the root view controller is your desired controller (or subclass the navigation controller)
    if viewController is YourViewControllerClass 

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        if let controller = storyboard.instantiateViewController(withIdentifier: "storyboardID") as? YourViewControllerClass 
            controller.modalPresentationStyle = .fullScreen
            self.present(controller, animated: true, completion: nil)
        

        return false
    

    // Tells the tab bar to select other view controller as normal
    return true

我没有测试上面的代码,因为我的实现略有不同并且有更多的变量。大体原理是一样的。

让我知道你的进展,如有必要,我会更新答案。

【讨论】:

我使用了您的代码,但它仍然无法正常工作。所以为我的 TabBarController 创建了一个新类并将您的代码粘贴到那里。你是这个意思吗?我应该写哪个类而不是YourViewControllerClass?也许你可以看看我的照片,我在我的原始帖子中链接了它。 嘿,你需要继承你的UITabBarController 并在这个类上实现UITabBarDelegate。在viewDidLoad 中,您需要执行self.delegate = self,然后当您尝试在底部选择一个选项卡时将触发上述方法。 YourViewControllerClass 是与故事板上的视图控制器关联的类(左侧的那个)。您需要继承 UIViewController 并将此类应用于该视图控制器。 耶!有用。非常感谢你的帮助。我忘记了 self.delegate = self.现在如果我想用一个按钮关闭它,我怎样才能设法回到 ViewController 是正确的? 我很高兴它有效!因此,在YourViewControllerClass 中,您只需要将操作绑定到按钮并调用self.dismiss(animated: true, completion: nil)。这只会关闭视图控制器,如果您在委托方法中返回 false,您的 UITabBarController 仍应位于离开时所在的选项卡上。 如果您在视图控制器之前有导航控制器。 1:创建新文件,2:使用导航 vc 对其进行分类,3:使用该类名作为 YourViewControllerClass【参考方案2】:

假设你符合UITabBarControllerDelegate,你可以实现:

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) 

    // here, you should edit "0" to be matched with your selected item
    // for instance, if there is 5 items and the desired item is in the middle, the compared value should be "2"
    if tabBarController.selectedIndex == 0 

        // simply, you will need to get the desired view controller and persent it:
        let desiredStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let desiredViewController = desiredStoryboard.instantiateViewController(withIdentifier: "storyboard id")

        present(desiredViewController, animated: true, completion: nil)

    

【讨论】:

我直接在情节提要中做了关系segue,所以标签栏项目是自动创建的。所以我已经有一个连接到标签栏控制器的视图,但是,我不想使用它,因为我不想在另一个视图中切换。我想让它弹出来。我该怎么办? 能否详细说明? 去看看我原来的帖子。我的问题是,由于 TabBarController,它没有以模态方式显示视图,而是切换到视图。之所以这样做是因为我是这样实现的,但现在我在问如何不切换视图而是以模态方式显示。这样它就会弹出我的实际视图。 好吧,如果我做对了,我发布的内容应该能满足您的要求。你试过了吗? 是的,我试过了。但无论如何,它现在有效。非常感谢您的帮助。【参考方案3】:
    let modalVC = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerIdentifier") 
    modalVC.modalTransitionStyle = .crossDissolve
    modalVC.modalPresentationStyle = .full or .overfullscreen // please check which of the options work
    self.present(modalVC, animated: true, completion: 

    )

【讨论】:

以上是关于从标签栏控制器模态显示视图的主要内容,如果未能解决你的问题,请参考以下文章

从模态视图切换到标签栏视图控制器并且不会丢失标签栏

ios标签栏点击显示模态视图黑屏

标签栏控制器中的模态视图

模态视图控制器隐藏标签栏

无法在标签栏控制器的顶部完全呈现模态视图控制器

带有 ios 故事板的标签栏