Sometimes the standard iOS tab bar just doesn't have the look or functionality you need for your app. In this case, you need to create a custom tab bar from scratch.
ctrl + drag
Creating an array of buttons will help us easily keep track of what button is getting pushed based on the tag or index of the button.
buttonsto hold your tab bar buttons.
@IBOutlet var buttons: [UIButton]!
ctrl + dragoutlets from all your buttons to the array.
var homeViewController: UIViewController! var searchViewController: UIViewController! var accountViewController: UIViewController! var trendingViewController: UIViewController!
We will use an array to hold all our ViewControllers. That way, we can simply pluck out any particular ViewController we want based on the button that was pushed.
var viewControllers: [UIViewController]!
0. We will link the button's tag value to this variable. So an initial value of
0will reference our first button.
var selectedIndex: Int = 0
Remember, all the ViewControllers we create in the Storyboard don't actually exist, until we set up a link to them somehow, like a segue. For our custom tab bar, we won't be using segues, so we will have to instantiate them when our main tab bar ViewController first loads.
ViewDidLoad()method, access the main Storyboard through code.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
storyboardand the particular ViewController's Storyboard ID
homeViewController = storyboard.instantiateViewControllerWithIdentifier("HomeViewController")
viewControllers = [homeViewController, searchViewController, accountViewController, trendingViewController]
Since we will be keeping track of which button was tapped, all the buttons can share the same action method.
ctrl + dragfrom your first button to the TabBarViewController to create an action.
ctrl + dragfrom every other button to the same
didPressTabso they are all sharing.
When a new tab button is tapped, the goal of this method is to get rid of the ViewController contents that was previously being displayed in the tabBarViewController, and replace it with the new ViewController content that corresponds to the new tab button that was pushed. In order to do this, we need to know two things: the previous Button and ViewController that were selected and the current Button and ViewController that are now selected.
selectedIndex will store the tag value of whatever button is selected. We set the initial value of
selectedIndex to 0, or button 1. When we tap a different button, until we assign
selectedIndex the tag value of the new button that was pushed, it actually represents the tag value of the previous button.
didPressTabmethod, we can keep track of the previous button like this...
let previousIndex = selectedIndex
Remember when we changed AnyObject to
UIButton when we hooked up our action? That is so we can access special properties of buttons, like accessing their tag value.
selectedIndexto the tag value of which ever button was tapped.
selectedIndex = sender.tag
You might be wondering why we don't just call
selectedTag instead. The reason is because we are going to plug that number into our
ViewControllers arrays in order to pluck out the correct item. When you access an item from an array at a certain point,
viewControllers, that point is called the index. The items in an array start at index 0 and go up by a value of 1 each item so that the 2nd item is at index 1, the 3rd is index 2 and so on.
So as you can see, it is no coincidence that we set our first button tag value to be
0, and then stored it at
index 0 in our
buttons array; just as we did for the corresponding index locations of the ViewControllers stored in our
didPressTabmethod, use your
previousIndexvalue to access your previous button and set it to the non-selected state.
buttons[previousIndex].isSelected = false
previousIndexto access the previous ViewController from the
let previousVC = viewControllers[previousIndex]
previousVC.willMove(toParentViewController: nil) previousVC.view.removeFromSuperview() previousVC.removeFromParentViewController()
didPressTabmethod, access your current selected button and set it to the selected state.
sender.isSelected = true
selectedIndexto access the current ViewController from the
let vc = viewControllers[selectedIndex]
viewWillAppearmethod of the ViewController you are adding)
contentViewof your tabBarViewController and add it as a subView of the
vc.view.frame = contentView.bounds contentView.addSubview(vc.view)
viewDidAppearmethod of the ViewController you are adding using
We will probably want to set a default tab to be initiated when we start our app for the first time. You can specify what tab you want to start with by setting the initial value of,
selectedIndex. Since we set the initial value of
0, our app will load with the 1st tab initiated.
viewDidLoadmethod, near the bottom, set the button state and call the
didPressTabmethod. We will plug in
buttons[selectedIndex]as arguments in the
didPressTabmethod to specify the initial button, since we haven't actually "tapped" a button yet and there is no
buttons[selectedIndex].isSelected = true didPressTab(buttons[selectedIndex])