在 TabBarController 中显示模态视图控制器
Posted
技术标签:
【中文标题】在 TabBarController 中显示模态视图控制器【英文标题】:Present Modal ViewController via TabBarController 【发布时间】:2020-01-23 20:33:50 【问题描述】:我有一个主要的tabBarController
,并且想在点击某个tabBarItem
时显示一个viewController
modally
。
我正在将viewControllers
加载到我的tabBarController
中...
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
委托设置为 self。
似乎没有任何工作,我希望有人可以指导我,因为我无法调试并找到现有的解决方案......
更新
所以我创建了一个dummyThirdVC
来替换setupViewControllers()
函数中的thirdVC
。在dummyThirdVC
中,我符合UITabBarControllerDelegate
并在viewDidLoad
中设置self.tabBarController.delegate = self
。然后我把delegate
方法输入到这个dummyThirdVC
中,在这个delegate
方法里面,我实例化了真正的thirdVC
来呈现。
delegate
方法终于正确触发了,但我现在的问题是,dummyThirdVC
及其视图必须首先加载并出现,然后才能设置和触发delegate
。
我怎么能不显示dummyThirdVC
并立即显示实例化的真实thirdVC
?我在setupViewControllers
函数中尝试过dummyThirdVC.viewDidLoad()
无济于事......
【问题讨论】:
【参考方案1】:我相信你的支票是错的。您正在检查 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
【讨论】:
谢谢你的回答,我有两个问题。我的第一个是委托方法永远不会被触发,无论检查如何。我的第二个是我试图以模态方式呈现这个第三个 VC,而不是已经呈现的任何 VC - 如果我有这个占位符 VC 然后实例化另一个,这是一个问题吗? 1.你说你试过调试它并打印出tabBarViewController
的委托,它和tabBarViewController
是同一个对象吗?
2.如果您在标签栏和模态展示中使用相同的 thirdVC 实例,您将收到错误消息,因为 thirdVC 在标签栏中处于活动状态,并且您正在尝试展示已经处于活动状态的视图控制器。
问题是我在 tabBarController 的一个 rootVC 中分配了 tabBarController 委托...打印和比较对象是我发现的,呃...以上是关于在 TabBarController 中显示模态视图控制器的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式选择单元格并转到 tabbarcontroller
将模态视图控制器解散回嵌入在 TabBarController 中的导航控制器堆栈导致崩溃
在带有分段控件的 UITabBarController 中模态显示导航视图控制器