如何从标签栏控制器更改标签栏项目

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

我得到了带有三个视图控制器设置的选项卡栏控制器。当我打开其中一个视图控制器时,它会更改其选项卡栏项 badgeValue。我想在到达第一个选项卡时更改此 badgeValue。

我创建了一个 Tabbarcontoller:UITabBarController class 但不知道如何轻松访问子视图的项目。这是来自我的 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()

    }
}

这里是子视图控制器的工作代码:

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!

}

我正在寻找一种简单的方法来访问子视图控制器或至少是它说的栏项目:

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

我不确定代表是否是正确的方式?

我会将栏项目留在朋友控制器之外。它不需要知道 tabBar。如果我是你,我会创建一个协议让你的 tabBarController 知道好友请求的数量已经改变。

首先,定义协议:

protocol FriendsRequestDelegate {
    func friendsRequestsDidChange(number: Int)
}

然后,将变量添加到您的 FriendsViewController:

weak var delegate: FriendsRequestDelegate?

并且,我们需要触发那个func,还是在FriendsViewController中,在获取好友请求数之后,添加;

delegate?.friendsRequestsDidChange(number: myFriendsRequests.count)

最后,让你的TabBarController符合这个协议;

extension TabBarController: FriendsRequestDelegate {

   func friendsRequestsDidChange(number: Int) {
       friendsBarItem.badgeValue = String(number)
   }

}

明白我的意思了吗?这样你的 friendsRequestController 就不知道 tabBar 并且它会保持你的代码干净。

我找到了一种访问 barItems 的非常简单的方法。我只需要访问 tabBar 项目数组:

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

这是我的 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()
    }
}

子视图控制器不再需要检查和更新 badgeValue。 (这对我来说很好,因为 getFriendsRequests_Methods_Destination(myFriendsRequest: UserInfo) 方法会在使用 (Firestore) 快照侦听器有新朋友请求时立即触发。)

我最初的方法是使用 tabBarController!.tabBar.items![2].badgeValue = "" 从每个子视图控制器单独访问 tabItem 但这对我来说是多余的。