Detect UITabBar Selected Index/ Item Changes that is set Programmatically
Along all answers here, if you subclassed UITabBarController
already, here's a simple solution for all tab bar changes (User initiated and programmatic ):
// Override selectedViewController for User initiated changes
override var selectedViewController: UIViewController? {
didSet {
tabChangedTo(selectedIndex: selectedIndex)
}
}
// Override selectedIndex for Programmatic changes
override var selectedIndex: Int {
didSet {
tabChangedTo(selectedIndex: selectedIndex)
}
}
// handle new selection
func tabChangedTo(selectedIndex: Int) {}
Previous answers are sufficient to "detect" the changes, however it does not detect which index is being pressed.
func selectItemWithIndex(value: Int) {
self.tabBarControllertabBarController.selectedIndex = value;
self.tabBar(self.tabBar, didSelectItem: (self.tabBar.items as! [UITabBarItem])[value]);
}
self.selectedIndex will not return the selected index right away. To check which item is being pressed, we would need to compare the item with the tabBarItems in our UITabBarController
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
if item == (self.tabBar.items as! [UITabBarItem])[0]{
//Do something if index is 0
}
else if item == (self.tabBar.items as! [UITabBarItem])[1]{
//Do something if index is 1
}
}
In swift, you can do it by overriding selectedIndex
property of UITabBarController
.
First subclass UITabBarController
and add all the following code.
//Overriding this to get callback whenever its value is changes
override var selectedIndex: Int {
didSet {
handleTabSelection(selectedIndex: selectedIndex)
}
}
Also add this delegate method of UITabBarControllerDelegate
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
//Tab tapped
guard let viewControllers = tabBarController.viewControllers else { return }
let tappedIndex = viewControllers.index(of: viewController)!
//Tab tapped at tappedIndex
handleTabSelection(selectedIndex: tappedIndex)
}
Finally, we call this method from both places so that all the cases are handled.
private func handleTabSelection(selectedIndex: Int) {
//Do something on tab selection at selectedIndex
}