0

I am new to swift. I am Working with TabBar controller. I have set the Tabbar controller and view controllers using a storyboard. But for some designing purpose, I need to add Tab bar items Programmatically. when I ran this code getting crashed stated 'Unexpectedly found nil' values for my outlets. Am I missing anything?

Thanks in Advance..

Here is my Code,

class TabbarController: UITabBarController,UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        tabBar.tintColor = UIColor.white
        tabBarItem.title = ""

        setTabBarItems()
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)
    {
       // print("hi", terminator: "")
    }

    func setTabBarItems(){

        let v1 = MyOrderViewController()

        v1.tabBarItem.image = UIImage(named: "footer_1")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
        v1.tabBarItem.selectedImage = UIImage(named: "footer_1")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
        v1.tabBarItem.title = "Orders"
        v1.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)

        let v2 = FavouritesViewController()

        v2.tabBarItem.image = UIImage(named: "footer_2")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
        v2.tabBarItem.selectedImage = UIImage(named: "footer_2")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
        v2.tabBarItem.title = "Favorites"
        v2.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)


        let v3 = FavouritesViewController()

        v3.tabBarItem.image = UIImage(named: "huggg")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
        v3.tabBarItem.selectedImage = UIImage(named: "huggg")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
        v3.tabBarItem.title = ""
        v3.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)


        let v4 = MoreViewController()

        v4.tabBarItem.image = UIImage(named: "footer_4")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
        v4.tabBarItem.selectedImage = UIImage(named: "footer_4")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
        v4.tabBarItem.title = "Account"
        v4.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)


        let v5 = MoreViewController()

        v5.tabBarItem.image = UIImage(named: "footer_5")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
        v5.tabBarItem.selectedImage = UIImage(named: "footer_5")?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
        v5.tabBarItem.title = "More"
        v5.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)

        let controllers = [v1, v2, v3, v4, v5]
        self.viewControllers = controllers
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Saravanan
  • 113
  • 1
  • 11
  • 1
    `MyOrderViewController()` creates a brand new instance which is not the instance in the storyboard and apart from that right after creating the instance the view of the controller is not loaded yet that means all UI related objects are `nil`. Instantiate the controllers and assign `image` and `title` in `viewDidLoad` in the controller – vadian Jun 06 '19 at 07:20
  • thanks for your answer. Can you please share some code. i cant get it. will i need to assign the outlet again in viewdidload? – Saravanan Jun 06 '19 at 08:55
  • Just move the 4 lines assigning the images and title in the corresponding view controller classes in `viewDidLoad`. – vadian Jun 06 '19 at 09:10
  • the problem is not in tab bar controller outlets. it is in view controllers outlets which i have added as a tabbar items. – Saravanan Jun 06 '19 at 09:17

1 Answers1

1

Reason of you issue is that you didn't connect you ViewControllers classes with storyboards views, so compiler can not instantiate outlets.

Instead of init method of you controllers, use UIStoryboard method instantiateViewController(withIdentifier:).

First create your storyboard

UIStoryboard(name: <storyboard_name>, bundle: nil)

than instantiate appropriate UIViewController using it identifier

let controller = storyboard.instantiateViewController(withIdentifier: <your_controller_identifier>)
Taras Chernyshenko
  • 2,729
  • 14
  • 27
  • thank you for your answer. i have changed the code but navigation controllers not showing in the top. – Saravanan Jun 06 '19 at 08:51
  • 1
    put your `UIViewController`s inside `UINavigationController`s. `let v1NavigationController = UINavigationController(rootViewController: v1)` and then use this controllers `self.viewControllers =[v1NavigationController, v2NavigationController...]` – Taras Chernyshenko Jun 06 '19 at 10:15
  • works great thank you for your help – Saravanan Jun 07 '19 at 03:14