I would like to know how do we detect when the selected TabBar Item or Index is changed when the changes is done programmatically?
self.tabBarController.selectedIndex = 1;
This two delegate function only detect changes when the tabBar Item was selected by user. It does not fire when the changes to the selectedIndex was done programmatically.
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
println("tabBarController didSelectViewController")
}
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
println("tabBar didSelectItem")
}
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
}
Swift 3
Here's a somewhat safer Swift-3 version, of what's been proposed above:
func selectItem(withIndex index: Int) {
if let controller = tabBarController,
let tabBar = tabBarController?.tabBar,
let items = tabBarController?.tabBar.items
{
guard index < items.count else { return }
controller.selectedIndex = index
controller.tabBar(tabBar, didSelect: items[index])
}
}
UITabBarController:
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if let items = tabBar.items {
items.enumerated().forEach { if $1 == item { print("your index is: \($0)") } }
}
}
Usage:
selectItem(withIndex: 1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With