Search code examples
iosswiftxcodeuiviewcontrolleruitabbarcontroller

How to create a referencing outlet for a Tab Bar Controller


I had created a tab bar in my storyboard, that I linked to a swift file to add some properties, and everything was working fine. But then I decided to change for a navigation controller, and now I can't set the properties I had added to my tab bar. screenshott

Does someone know how I can set the properties for the tab bar controller ? (I don't really see the difference between a tab bar and a tab bar controller).


Solution

  • The UITabBarController is a special kind of UIViewController that has a built-in UITabBar. Because the tab bar comes already included in this class, there is no need to set up an @IBOutlet for the tab bar, or to add delegate protocol conformance. Inside your Tab Bar ViewController class definition, you can just refer to the tab bar by the variable name tabBar and everything else will work exactly the same as in your screenshot (I have included a picture at the bottom of this answer for comparison.)

    To get it to work, it is necessary to first set up the UITabBarController ViewController correctly. Here are the steps I took:

    1. In a new Xcode project, delete the default ViewController.swift file and delete the view controller from Main.storyboard.

    2. From the + Library menu in the top right corner, scroll down until you find the Tab Bar Controller. It should be in the section with the other view controllers. Drag and drop one of these onto the now-empty storyboard.

    3. In your file menu on the left sidebar, right click -> New File -> Cocoa Touch Class -> name it whatever you want (I chose just "ViewController"), and for Subclass of:, select UITabBarController. You won't have to check the "Also create XIB file" box.

    4. In Main.storyboard, select the UITabBarController and under the Attributes Inspector (in the right-hand sidebar), set its class to whatever name you chose in the previous step. Now you can see the .swift file connected to the storyboard item when you view them in Assistant mode under "Adjust Editor Options" -- just like you have in your screenshot.

    5. Copy and paste all the tab bar appearance setup you currently have in your screenshot into the view controller's viewDidLoad method, but with this change: Everywhere you have "tabBarMenu" (which seems to have been the name of your old @IBOutlet?), change it to just "tabBar."

    You should end up with this in your View Controller .swift file:

    import UIKit
    
    // This is not the same class as UITabBar! No delegate protocol conformance is needed (it's already built in to this kind of View Controller)
    class ViewController: UITabBarController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            // The controller's Tab Bar doesn't need (or even allow) an @IBOutlet, because the UITabViewController class is designed with the Tab Bar built-in and already assigned to the name "tabBar"
            
            // Here are all the same settings you had in your screenshot:
            tabBar.layer.shadowColor = UIColor.gray.cgColor
            tabBar.layer.shadowOpacity = 0.5
            tabBar.layer.shadowOffset = CGSize.zero
            tabBar.layer.borderColor = UIColor.clear.cgColor
            tabBar.layer.borderWidth = 0
            tabBar.clipsToBounds = false
            tabBar.backgroundColor = UIColor.white
            
            UITabBar.appearance().shadowImage = UIImage()
            UITabBar.appearance().backgroundImage = UIImage()
            
        }
    }
    

    And the result will be this: enter image description here