Search code examples
iosswiftuiviewcontrollerdelegatesuitabbarcontroller

How to change a tab bar item from the tab bar controller


I got tab bar controller with three view controllers setup. One of those view controllers changes its tab bar item badgeValue when I open it. I would like to change this badgeValue already when I arrive at the first tab.

I created a Tabbarcontoller: UITabBarController class but don't know how to easily access the items of the sub views. Here is the code from my Tabbarcontoller class:

    class TabBarController: UITabBarController, MainMethodsDelegate {

    var myFriendsRequests: [UserInfo] = []
    var friendRequestsCount: Int = 0

    func getFriendsRequests_Methods_Destination(myFriendsRequest: UserInfo) {
        myFriendsRequests.append(myFriendsRequest)
        self.friendRequestsCount = myFriendsRequests.count

        DispatchQueue.main.async {
            //friendsBarItem.badgeValue = String(self.friendRequestsCount)
        }
    }

    let mainMethods = MainMethods()

    override func viewDidLoad() {
        super.viewDidLoad()

        mainMethods.delegate = self
        mainMethods.getFriendsRequests()

    }
}

And here the working code from the sub view controller:

class FriendsViewController: UIViewController, MainMethodsDelegate {

    var myFriendsRequests: [UserInfo] = []
    var friendRequestsCount: Int = 0

    func getFriendsRequests_Methods_Destination(myFriendsRequest: UserInfo) {
        myFriendsRequests.append(myFriendsRequest)
        self.friendRequestsCount = myFriendsRequests.count

        DispatchQueue.main.async {
            self.friendsBarItem.badgeValue = String(self.friendRequestsCount)
        }

    }

    let mainMethods = MainMethods()

    override func viewDidLoad() {
        super.viewDidLoad()

        mainMethods.delegate = self
        mainMethods.getFriendsRequests()
    }

    @IBOutlet weak var friendsBarItem: UITabBarItem!

}

I'm looking for a simple way to access the sub view controllers or at least the bar items where it says:

//friendsBarItem.badgeValue = String(self.friendRequestsCount)

I'm not sure if delegates is the right way to go?


Solution

  • I've found a quite simple way to access the barItems. I only had to access the array of tabBar items with:

    tabBar.items![2].badgeValue = ""

    Here is my code for the UITabBarController:

    class TabBarController: UITabBarController, MainMethodsDelegate {
    
        var myFriendsRequests: [UserInfo] = []
        var friendRequestsCount: Int = 0
    
        func getFriendsRequests_Methods_Destination(myFriendsRequest: UserInfo) {
            myFriendsRequests.append(myFriendsRequest)
            self.friendRequestsCount = myFriendsRequests.count
    
            DispatchQueue.main.async {
    
                self.tabBar.items![2].badgeValue = String(self.friendRequestsCount)
    
            }
        }
    
        let mainMethods = MainMethods()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            mainMethods.delegate = self
            mainMethods.getFriendsRequests()
        }
    }
    

    The sub view controller does not need to check and update the badgeValue anymore. (This is fine in my case since the getFriendsRequests_Methods_Destination(myFriendsRequest: UserInfo) method gets triggered as soon as there is a new friends request anyways using a (Firestore) snapshot listener.)

    My initial way was to access the tabItem from each of the sub view controllers individually using tabBarController!.tabBar.items![2].badgeValue = "" But this would have been redundant in my case.