2

I have a tab bar controller in my application that has 4 tabs. One of them is supposed to display one of 2 scenes based on the response from the API: either an empty view if there is no data or a segmented control if there is data. Here are the storyboards with the setup:

Tab bar storyboard Views storyboard

On both an empty view and a view with data I have a button that should "click" one of the buttons on a tab bar (switch to another tab).

For now this is what I'm doing:

Showing the view with data:

class EmptyTasksVC: ViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        if(there_is_data){
            let storyboard = UIStoryboard(name: "TaskTodoList", bundle: nil)
            let vc = storyboard.instantiateViewController(withIdentifier: "TaskListSegmentedControl")

            let childNavigation = UINavigationController(rootViewController: vc)
            childNavigation.willMove(toParent: self)
            addChild(childNavigation)
            childNavigation.view.frame = view.frame
            view.addSubview(childNavigation.view)
            childNavigation.didMove(toParent: self)
         }
    }
}

Finding the tab bar on button click from view with data:

@objc func newTaskAction(sender: UIButton!) {
    let viewController = self.findViewController()
    let tabBar = viewController?.parent?.parent?.parent?.parent?.parent as! UITabBarController
    tabBar.selectedIndex = 2
}
...

extension UIView {
    func findViewController() -> UIViewController? {
        if let nextResponder = self.next as? UIViewController {
            return nextResponder
        } else if let nextResponder = self.next as? UIView {
            return nextResponder.findViewController()
        } else {
            return nil
        }
    }
}

If I want to get to the button from empty view I have to remove 2 "parents" from the chain.

There MUST be a better way to do it... Is my architecture wrong? How can I get to the tab bar from the embedded view if I don't know how many views are on the way?

1 Answers1

1

A ViewController already has a property tabBarController with description as

// If the view controller has a tab bar controller as its ancestor, return it. Returns nil otherwise.

so you can directly access the TabBar Controller your viewController is embedded in,

self.tabBarController?.selectedIndex = 2
Kamran
  • 14,987
  • 4
  • 33
  • 51