以编程方式从 UITabBarController 模态呈现 UIViewController

Present Modally UIViewController From UITabBarController Programmatically

大家好,当用户 select 是我的标签栏的索引 1 时,我需要模态显示 View Controller

我创建了一个 UITabBarController class,我在其中实例化了所有要与 tabBar 一起显示的视图控制器

在这部分代码中,我为 tabBar 的索引 1 管理视图控制器的模式呈现

问题是,当我 select 索引 1 时, VCIndex1 控制器被调用两次...一次是为了正常显示 tabBar,另一次是为了模态呈现

如何在没有标签栏调用控制器 x2 次的情况下以模态方式呈现 VCIndex1

class TabBarController: UITabBarController {


 override func viewDidLoad() {
    super.viewDidLoad()

    delegate = self

    tabBar.barTintColor = UIService.Color.backgroundColor
    tabBar.isTranslucent = false

    tabBar.tintColor = UIService.Color.primaryColor
    tabBar.selectedItem?.badgeColor = UIService.Color.secondaryColor
    tabBar.unselectedItemTintColor = UIService.Color.tertiaryColor
    tabBar.shadowImage = UIImage()

    let vcIndex0 = UINavigationController(rootViewController: VC0())
    vcIndex0 = UIImage(systemName: "rosette")

    let vcIndex1 = UINavigationController(rootViewController: VC1())
    vcIndex1 = UIImage(systemName: "plus.square.on.square")

    let vcIndex2 = UINavigationController(rootViewController: VC2())
     vcIndex2 = UIImage(systemName: "tag")

    viewControllers = [vcIndex0, vcIndex1, vcIndex2]


}

override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    let indexOfTab = tabBar.items?.firstIndex(of: item)

        if indexOfTab == 1 {

            let vc = VC1()
            vc = .fullScreen
            present(vc, animated: true, completion: nil)

        }

    }

}

您可能想要实现 shouldSelect (Apple Docs) 并在那里处理制表符检测和模式显示。

试一试:

class TabBarController: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        delegate = self

        tabBar.barTintColor = .lightGray // UIService.Color.backgroundColor
        tabBar.isTranslucent = false

        tabBar.tintColor = .green // UIService.Color.primaryColor
        tabBar.selectedItem?.badgeColor = .blue // UIService.Color.secondaryColor
        tabBar.unselectedItemTintColor = .cyan // UIService.Color.tertiaryColor
        tabBar.shadowImage = UIImage()

        let vcIndex0 = UINavigationController(rootViewController: VC0())
        vcIndex0.tabBarItem = UITabBarItem(title: "0", image: UIImage(systemName: "rosette"), tag: 0)

        // just create a plain UIViewController here (it will never be seen)
        //let vcIndex1 = UINavigationController(rootViewController: VC1())
        let vcIndex1 = UIViewController()
        vcIndex1.tabBarItem = UITabBarItem(title: "1", image: UIImage(systemName: "plus.square.on.square"), tag: 0)

        let vcIndex2 = UINavigationController(rootViewController: VC2())
        vcIndex2.tabBarItem = UITabBarItem(title: "2", image: UIImage(systemName: "tag"), tag: 0)

        viewControllers = [vcIndex0, vcIndex1, vcIndex2]

    }

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

        if viewController == tabBarController.viewControllers?[1] {
            let vc1 = VC1()
            vc1.modalPresentationStyle = .fullScreen
            present(vc1, animated: true, completion: nil)
            return false
        }

        return true

    }

    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        // if you want to do something based on selected tab
        if let indexOfTab = tabBar.items?.firstIndex(of: item) {
            print("didSelect:", indexOfTab)
        }
    }

}

class VC0: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
    }
}

class VC1: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .green
        let tap = UITapGestureRecognizer(target: self, action: #selector(dismissMe))
        view.addGestureRecognizer(tap)
    }
    @objc func dismissMe() -> Void {
        dismiss(animated: true, completion: nil)
    }
}

class VC2: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .blue
    }
}