通过 TabBarController 呈现模态 ViewController

Present Modal ViewController via TabBarController

我有一个主 tabBarController 并且想在点击某个 tabBarItem 时显示一个 viewController modally

我正在 tabBarController 中加载 viewControllers 作为...

func setupViewControllers() {
    self.tabBar.isHidden = false

    if let firstVC = storyboard?.instantiateViewController(withIdentifier: "first") as? FirstViewController, let secondVC = storyboard?.instantiateViewController(withIdentifier: "second") as? SecondViewController, let thirdVC = storyboard?.instantiateViewController(withIdentifier: "third") as? ThirdViewController, let fourthVC = storyboard?.instantiateViewController(withIdentifier: "fourth") as? FourthViewController, let fifthVC = storyboard?.instantiateViewController(withIdentifier: "fifth") as? FifthViewController {

        let firstNavController = UINavigationController(rootViewController: firstVC)
        let secondNavController = UINavigationController(rootViewController: secondVC)
        let fourthNavController = UINavigationController(rootViewController: fourthVC)
        let fifthNavController = UINavigationController(rootViewController: fifthVC)

        firstNavController.tabBarItem.image = image
        secondNavController.tabBarItem.image = image
        fourthNavController.tabBarItem.image = image
        fifthNavController.tabBarItem.image = image     
        thirdVC.tabBarItem.image = image

        tabBar.tintColor = nil

        //Load tabBar viewControllers
        viewControllers = [homeNavController, postNavController, plusMenuVC, meetupNavController, profileNavController]
    }
}

然后我使 tabBarViewController 符合 UITabBarControllerDelegate 以调用方法...

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    if tabBarController.selectedIndex == 2, let thirdVC = viewController as? ThirdViewController {
        thirdVC.modalPresentationStyle = .overFullScreen
        thirdVC.modalTransitionStyle = .crossDissolve
        present(thirdVC, animated: true, completion: nil)
        return false
    } else { return true }
}

然而,以上永远不会被触发。我尝试在 viewDidLoad

中设置
self.delegate = self

我尝试将根导航控制器及其祖先 tabBarController 委托给自己。

似乎没有任何效果,我希望有人能指导我,因为我一直无法调试并找到现有的解决方案...

更新 所以我创建了一个 dummyThirdVC 来替换 setupViewControllers() 函数中的 thirdVC 。在 dummyThirdVC 中,我符合 UITabBarControllerDelegate,在 viewDidLoad 中,我设置了 self.tabBarController.delegate = self。然后我把delegate方法输入到这个dummyThirdVC里面,在这个delegate方法里面,我实例化了真正的thirdVC来呈现

delegate 方法终于正确触发,但我现在的问题是,dummyThirdVC 及其视图必须首先加载并出现,然后才能设置和触发 delegate

我怎么能不显示 dummyThirdVC 而立即显示实例化的真实 thirdVC?我在我的 setupViewControllers 函数中尝试了 dummyThirdVC.viewDidLoad() 但无济于事...

我相信你的支票是错误的。您正在检查 selectedIndex 是否为 2,但是 selectedIndex 的值将始终是实际选项卡栏的选定索引,而不是将要选择的索引,所以您基本上是永远不会达到 selectedIndex 作为 2。

您也不能显示已经激活的视图控制器,并且 thirdVC 在您的 tabBar 中已经激活,因此您会收到错误消息。解决方法是使用 viewController 作为标签栏中图像和标题的占位符,并实例化另一个用于呈现。

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    if viewController is ThirdViewController {
        let vcToPresent = storyboard?.instantiateViewController(withIdentifier: "third") as? ThirdViewController
        vcToPresent.modalPresentationStyle = .overFullScreen
        vcToPresent.modalTransitionStyle = .crossDissolve
        present(vcToPresent, animated: true, completion: nil)
        return false
    }
    return true
}