Reputation: 2773
Hi everyone I need to present a View Controller
modally when the user selects the index 1 of my Tab bar.
I created a UITabBarController
class where I instantiate all the view controllers to be shown with the tabBar
In this part of the code I manage the modal presentation of the view controller for the index 1 of the tabBar
The problem is that when I select index 1 the VCIndex1 controller is called twice ... once for the normal display of the tabBar and another time for the modal presentation
How can I present VCIndex1 modally without the tab bar calling the controller x2 times?
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)
}
}
}
Upvotes: 0
Views: 763
Reputation: 77431
You probably want to implement shouldSelect
(Apple Docs) and handle your tab-detection and modal presentation there.
Give this a try:
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
}
}
Upvotes: 1