Search code examples
swiftuitabbarcontrollerappdelegateuitabbaritemuicontainerview

Programmatically assign view controller to tab bar controller


I am fairly new to swift and am trying to create a movie database application using TMDB from Apiary.

I have created the layout of the view controllers for one category. However, I am planning to have multiple categories, the but only difference between them is the data I retrieve from the API. For example "now_playing" key gets the now playing list and the "top_rated" key gets the top rated list of movies. When I was initially doing this I created the tab bar controller in AppDelegate.swift and added the ViewControllers to it by getting them programmatically from the storyboard with the method instantiateViewControllerWithIdentifier. Then finally the I set the TabBarController's view controllers to the two ViewControllers by doing this: tabBarController.viewControllers = [nowPlayingNavigationController, topRatedNavigationController]

This was working fine. Later to add customizability I tried creating a slide out menu using container views. Story board for root View Controller and Menu which is a ViewController with a tableview inside of it.

At this point I was unable to embed the programmatically created Tab Bar Controller into the large container view on the right side of the ContainerViewController. Since I could not figure out how to programmatically do this, I attempted to create a TabBarController in main.storyboard and gave it a StoryboardID and tried setting it to a variable TabBarController in AppDelegate.swift.

Tried embedding TabBarController in container

var tabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController

later when I try to modify the TabBar and assign the previously created ViewControllers to the TabBarController it simply does not work.

tabBarController.viewControllers = [nowPlayingNavigationController, topRatedNavigationController]
tabBarController.tabBar.barStyle = .Black
tabBarController.tabBar.tintColor = UIColor.orangeColor()

I am not sure why this isn't working please help me out.

Simulated Application, the TabBarController is not updating from the code in AppDelegate.swift

AppDelegate.Swift didFinishLaunchingWithOptions function for reference

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    //window = UIWindow(frame: UIScreen.mainScreen().bounds)

    let storyboard = UIStoryboard(name: "Main", bundle: nil)

    let nowPlayingNavigationController = storyboard.instantiateViewControllerWithIdentifier("FlicksNavigationController") as! UINavigationController
    let nowPlayingViewController = nowPlayingNavigationController.topViewController as! MoviesViewController
    nowPlayingViewController.endpoint = "now_playing"
    nowPlayingNavigationController.tabBarItem.title = "Now Playing"
    nowPlayingNavigationController.tabBarItem.image = UIImage(named: "popular")
    nowPlayingNavigationController.navigationBar.barStyle = .BlackTranslucent

    let topRatedNavigationController = storyboard.instantiateViewControllerWithIdentifier("FlicksNavigationController") as! UINavigationController
    let topRatedViewController = topRatedNavigationController.topViewController as! MoviesViewController
    topRatedViewController.endpoint = "top_rated"
    topRatedNavigationController.tabBarItem.title = "Top Rated"
    topRatedNavigationController.tabBarItem.image = UIImage(named: "topRated")

    topRatedNavigationController.navigationBar.barStyle = .BlackTranslucent



    var tabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController

    //tabBarController.viewControllers = [nowPlayingNavigationController, topRatedNavigationController]
    tabBarController.tabBar.barStyle = .Black
    tabBarController.tabBar.tintColor = UIColor.orangeColor()



    //let containerViewController = storyboard.instantiateViewControllerWithIdentifier("ContainerViewController") as! ContainerViewController
    //let mainContainerView = containerViewController.mainContainerView

    //window?.rootViewController = tabBarController
    //window?.makeKeyAndVisible()


    return true
}

Solution

  • I initially had no idea of how to fix this problem but someone helped me out and now I got it working.

    Instead of controlling the TabBarController in the AppDelegate.swift it has to be done in ContainerViewController.swift and it should be done in the prepareForSegue method.

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
        if segue.destinationViewController.isKindOfClass(UITabBarController) {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
    
            let nowPlayingNavigationController = storyboard.instantiateViewControllerWithIdentifier("FlicksNavigationController") as! UINavigationController
            let nowPlayingViewController = nowPlayingNavigationController.topViewController as! MoviesViewController
            nowPlayingViewController.endpoint = "now_playing"
            nowPlayingNavigationController.tabBarItem.title = "Now Playing"
            nowPlayingNavigationController.tabBarItem.image = UIImage(named: "popular")
            nowPlayingNavigationController.navigationBar.barStyle = .BlackTranslucent
    
            let topRatedNavigationController = storyboard.instantiateViewControllerWithIdentifier("FlicksNavigationController") as! UINavigationController
            let topRatedViewController = topRatedNavigationController.topViewController as! MoviesViewController
            topRatedViewController.endpoint = "top_rated"
            topRatedNavigationController.tabBarItem.title = "Top Rated"
            topRatedNavigationController.tabBarItem.image = UIImage(named: "topRated")
    
            topRatedNavigationController.navigationBar.barStyle = .BlackTranslucent
    
    
    
            let tabVC = segue.destinationViewController as! UITabBarController
    
            tabVC.viewControllers = [nowPlayingNavigationController, topRatedNavigationController]
            tabVC.tabBar.barStyle = .Black
            tabVC.tabBar.tintColor = UIColor.orangeColor()
    
        }
    }
    

    I believe this has to be done since the TabBarController is instantiated in StoryBoard and is contained in a containerView that is inside of the ContainerViewController. So, the way to control it would be inside the prepareForSegue method rather than in AppDelegate.swift.