How to change UITabBarItem Badge position?

霸气de小男生 提交于 2019-12-01 21:27:26

try this:

func repositionBadge(tabIndex: Int){

    for badgeView in self.tabBarController!.tabBar.subviews[tabIndex].subviews {

        if NSStringFromClass(badgeView.classForCoder) == "_UIBadgeView" {
            badgeView.layer.transform = CATransform3DIdentity
            badgeView.layer.transform = CATransform3DMakeTranslation(-17.0, 1.0, 1.0)
        }
    }
}

pay attention, tabIndex starts from 1

Based on Marco Santarossa's answer, I updated it by making it into a UITabBarController extension, with a few additional tweaks:

extension UITabBarController {
    func repositionBadgeLayer(_ badgeView: UIView) {
        if NSStringFromClass(badgeView.classForCoder) == "_UIBadgeView" {
            badgeView.layer.transform = CATransform3DIdentity
            badgeView.layer.transform = CATransform3DMakeTranslation(-17.0, 1.0, 1.0)
        }
    }

    func repositionBadges(tab: Int? = nil) {
        if let tabIndex = tab {
            for badgeView in self.tabBar.subviews[tabIndex].subviews {
                repositionBadgeLayer(badgeView)
            }
        } else {
            for tabBarSubviews in self.tabBar.subviews {
                for badgeView in tabBarSubviews.subviews {
                    repositionBadgeLayer(badgeView)
                }
            }
        }
    }
}

Now you can use it on your custom UITabBarController class, simply call:

  1. repositionBadges() to apply on every tab bar item available in the tab bar

    or

  2. repositionBadges(0) with 0 referring to the tab bar item index, for selective application

Here is a simple example with a red spot githubGist. And of course, you can custom the your own badgeView = UIView() if you wanna add a label inside.

Swift 4.2

fileprivate let tabBarItemTag: Int = 10090
extension UITabBar {
    public func addItemBadge(atIndex index: Int) {
        guard let itemCount = self.items?.count, itemCount > 0 else {
            return
        }
        guard index < itemCount else {
            return
        }
        removeItemBadge(atIndex: index)

        let badgeView = UIView()
        badgeView.tag = tabBarItemTag + Int(index)
        badgeView.layer.cornerRadius = 5
        badgeView.backgroundColor = UIColor.red

        let tabFrame = self.frame
        let percentX = (CGFloat(index) + 0.56) / CGFloat(itemCount)
        let x = (percentX * tabFrame.size.width).rounded(.up)
        let y = (CGFloat(0.1) * tabFrame.size.height).rounded(.up)
        badgeView.frame = CGRect(x: x, y: y, width: 10, height: 10)
        addSubview(badgeView)
    }

    //return true if removed success.
    @discardableResult
    public func removeItemBadge(atIndex index: Int) -> Bool {
        for subView in self.subviews {
            if subView.tag == (tabBarItemTag + index) {
                subView.removeFromSuperview()
                return true
            }
        }
        return false
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!