用户选择选项卡时如何重置 UITabBarController 的选项卡(或选项卡控制器)?

Posted

技术标签:

【中文标题】用户选择选项卡时如何重置 UITabBarController 的选项卡(或选项卡控制器)?【英文标题】:How to reset tab (or tab controller) of UITabBarController when user select tab? 【发布时间】:2017-04-28 10:32:30 【问题描述】:

Swift:我有 UITabBarController,有 8 个标签。当用户选择包括更多选项卡在内的任何选项卡时,我想通过弹出到 rootView 控制器来重置所选选项卡的内容?

这是怎么做到的?

我尝试通过以下方法重置导航控制器,它适用于底部可见的标签,但不适用于More 标签。

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

override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem)

【问题讨论】:

你已经尝试了什么?显示一些代码,显示您遇到的错误或更详细地解释它 @Scriptable 我试图在 tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) 方法中重置导航控制器 【参考方案1】:

一个干净的方式来做到这一点:

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) 
    let index = tabBarController.selectedIndex
    if index == NSNotFound || index > 4 
        tabBarController.moreNavigationController.popToRootViewController(animated: false)
        return
    
    let navController = tabBarController.viewControllers?[tabBarController.selectedIndex] as? UINavigationController
    navController?.popToRootViewController(animated: false)

为您的 UITabViewContoller 创建一个自定义类,设置一个委托并将那段代码放在那里。

【讨论】:

kamil3 它适用于底部可见的标签,但不适用于更多标签:( @GauravBorole 一般来说,Apple 会劝阻在标签栏中使用超过 5 个标签:developer.apple.com/ios/human-interface-guidelines/ui-bars/…。当然,这并不能改变你是对的事实。 kamil3 是的,没错,但情况就是这样:) @GauravBorole 我编辑了我的答案 - 原来 UITabBarController 有 moreNavigationController 属性。符合您的要求吗? kamil3 谢谢它也适用于更多标签。但我认为对于 MoreTab,我们需要添加检查是否是 MoreTab 索引然后 Pop 到根视图。【参考方案2】:

您可以为您的 tabBar 创建一个 UITabBarController 类,并在该类中覆盖 tabBar didSelect 方法,从它们选择您可以 popViewController 的任何选项卡

 class TabBarViewController: UITabBarController 
        override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) 
            let navigationController1 =  self.viewControllers![0] as? UINavigationController
            navigationController1!.popViewController(animated: false)

            let navigationController2 =  self.viewControllers![1] as? UINavigationController
            navigationController2!.popToRootViewController(animated: false)


            let navigationController3 =  self.viewControllers![2] as? UINavigationController
            navigationController3!.popToRootViewController(animated: false)

            let navigationController4 =  self.viewControllers![3] as? UINavigationController
            navigationController4!.popToRootViewController(animated: false)

        

【讨论】:

它适用于底部可见的标签,但不适用于更多标签:( 在问题中添加故事板的屏幕截图 ViewController 以编程方式添加到 UITabBarController。但我想无论您使用 Storyboard 还是 Programatic 方式都没有关系。【参考方案3】:

使用UITabbarControllerviewControllers 属性。 viewControlers 是用于 UITabbarController 的 UIViewController 数组。选择标签栏(控制器)时交换/移动视图控制器的位置。

使用 tabbar(controller) 的委托方法来处理这些操作,例如: 斯威夫特 3

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) 
    if var viewcontrollers = tabBarController.viewControllers 
        viewcontrollers.remove(at: tabBarController.selectedIndex)
        viewcontrollers.insert(viewController, at: 0)
        tabBarController.viewControllers = viewControllers
    

如果您可以访问已实现的 tabbarController,您也可以使用此委托方法。

func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) 
 // Write a similar code to exchange/move view controllers using tabbarController instance.       

【讨论】:

【参考方案4】:

这对我有用。

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) 
    guard let navigationController = tabBarController.viewControllers?[tabBarController.selectedIndex] as? UINavigationController else 
        return
    

    navigationController.popToRootViewController(animated: false)

【讨论】:

这对我不起作用。你把它放在你的 UITabBarController 类中了吗? (我在分配给 TabBar Interface Builder 项的自定义 UITabBarController 类中尝试了此操作)。【参考方案5】:

要完全支持More,请创建如下自定义类:

class Main_TabBarController: UITabBarController 

    override func viewDidLoad() 
        super.viewDidLoad()

        self.customizableViewControllers = []  //remove Edit from More (OPTIONAL)
    

    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) 
        if let index = tabBar.items?.firstIndex(of: item) 
            if let count = viewControllers?.count, count > 5, index == 4 
                DispatchQueue.main.async 
                    self.moreNavigationController.popToRootViewController(animated: false)
                
             else if let vcs = viewControllers, let vc = vcs[index] as? UINavigationController 
                DispatchQueue.main.async 
                    vc.popToRootViewController(animated: false)
                
            
        
    


【讨论】:

以上是关于用户选择选项卡时如何重置 UITabBarController 的选项卡(或选项卡控制器)?的主要内容,如果未能解决你的问题,请参考以下文章

用户切换浏览器选项卡时如何从 JApplet 中隐藏 JDialog?

每次选择标签栏项目时如何重置导航堆栈?

当用户返回到 UITabBarController 选项卡时如何刷新表数据

当用户切换选项卡时,如何允许 Easeljs Tickers 保持活动状态

如何使用 React Navigation 5.x 在不同的选项卡中重置堆栈

以编程方式切换选项卡时清除根视图控制器的变量