13

I have a navigation controller with 4 tab bar items. Each one has a navigation controller inside. I want to be able to change the 4th tab bar badge number when I get push notification, no matter in what view or tab am I. I need to use the auto-layout so I can't use any programmatically solution inside the app delegate. I started the project from a single view template.

I tried to go to the desired tab, change the badge value and come back but of course it didn't work. The tabBarController seems to have only references to the current tab bar item.

    var current = self.tabBarController?.selectedIndex
    self.tabBarController?.selectedIndex = 3
    self.navigationController?.tabBarItem.badgeValue = "34"
    self.tabBarController?.selectedIndex = current!
pinolo
  • 347
  • 2
  • 7
  • 20

3 Answers3

37

No need to select that index to update badge value. Take an array of tab bar items. The select item at the index which you want to update and then set it badge value. See below I have done for 4th tab bar item.

Swift 5.0

if let items = self.tabBarController?.tabBar.items as NSArray? {
    let tabItem = items.object(at: 3) as! UITabBarItem
    tabItem.badgeValue = "34"
}
Kampai
  • 22,848
  • 21
  • 95
  • 95
  • 1
    Neat and clean! Thank you very much! I've seen that in Obj-C it was done using objectAtIndex(index) but I couldn't find from where to call it. Thank you again! – pinolo Nov 28 '14 at 01:11
  • @Kampai how would this need to be modified to perform the badge icon update in the app delegate? I can't do self.tabBarController from there? – user2363025 Sep 07 '15 at 09:10
  • 4
    @user2363025: You need to get `rootViewController` to update badge from `AppDelegate`. Like this `let rootViewController = self.window?.rootViewController as! UITabBarController! let tabArray = rootViewController?.tabBar.items as NSArray! let tabItem = tabArray.objectAtIndex(1) as! UITabBarItem tabItem.badgeValue = "34"` – Kampai Sep 07 '15 at 09:24
  • @Kampai thank you for your response. I tried your code but I am geting the error: Could not cast value of type 'UINavigationController' (0x198395090) to 'UITabBarController' pointing to the line: let rootViewController = self.window?.rootViewController as! UITabBarController! – user2363025 Sep 07 '15 at 09:35
  • @Kampai Just to note my layout is a view controller for a login page as the root and on login, a tab bar controller is opened – user2363025 Sep 07 '15 at 09:37
  • @user2363025: Because your `rootViewController` is `navigationController`, What you have to do is get `tabBarController ` object after you login. So you can get its object by using Storyboard identifier. – Kampai Sep 07 '15 at 09:40
  • @Kampai when the user is logged in, the root controller is skipped based on a bool value. So in which file would I update my badge icon? Is there any controller where an event is triggered when the tabgroup is opened or anything like that? Do I just put the code in the viewDidLoad of the default active tab on tab bar open? – user2363025 Sep 07 '15 at 09:44
  • 1
    @user2363025 Yes, from base on your login if your case is to show tabs than you can just put badge update code (Written in answer) in `viewDidLoad` method of visible controller. – Kampai Sep 07 '15 at 09:47
  • i have to do same thing but i have api from which i m getting count that i have to set as badge on tab bar index 0 so in which Class i will call api to update tab bar index badge whether it is second index or another index – Dilip Tiwari Oct 19 '18 at 17:01
  • Create a subclass of `UITabBarController`, in that create a method `-setBadgeCount:(int)badgeValue` and update badge value in this method. You can call this method from anywhere in the application. – Kampai Oct 22 '18 at 06:03
7

Shorter:

let tabItem = self.tabBarController?.tabBar.items![3]
let tabItem.badgeValue = "34"
Eric Johnson
  • 1,087
  • 1
  • 11
  • 16
  • 2
    And always better to use "if let": if let tabItem = self.tabBarController?.tabBar.items![3] { tabItem.badgeValue = 34 } – Adagio Feb 13 '17 at 15:23
3
extension UITabBarController {
    func increaseBadge(indexOfTab: Int, num: String) {
        let tabItem = tabBar.items![indexOfTab]
        tabItem.badgeValue = num
    } 
}

and you can call it like this:

self.tabBarController?.increaseBadge(indexOfTab: 3, num: "34")
Bassant Ashraf
  • 1,531
  • 2
  • 16
  • 23