How to adjust tab bar badge position?

2020-03-13 08:40发布

问题:

I'm displaying badge on tab bar but when number increase it goes out to tab bar item like shown in image

I want to move the badge view slightly left so it fit on selected tab image.i tried as described here but no luck. So is there is any way to adjust badge view position?Any help would be appreciated.

回答1:

I found Kateryna's answer to be useful in putting me on the right track, but I had to update it a little:

func repositionBadge(tab: Int){

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

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

}

Please note the tab integer is NOT zero-indexed, so the first tab will be number 1, the 2nd number 2, etc.



回答2:

When you update your badge value, add such a method:

func updateBadge(#value: UInt, tabBarItemTag: Int) {
     self.viewControllerForTag(tabBarItemTag)?.tabBarItem.badgeValue = value
     for badgeView in (tabBar.subviews[tabBarItemTag] as! UIView).subviews {
         let className = "\(_stdlib_getDemangledTypeName(badgeView))"
         if className.rangeOfString("BadgeView").location != NSNotFound {
             badgeView.layer.transform = CATransform3DIdentity
             badgeView.layer.transform = CATransform3DMakeTranslation(0.0, 10.0, 20.0)
         }
     }
}

You need to play a bit with a second CATransform3DMakeTranslation to make right positioning. In this code badge moves a bit on bottom/left. First CATransform3DMakeTranslation is needed to pretend badge moving. It is a Swift code, but you can convert it to Objective-C easily.



回答3:

Badge align to your tab bar image by default.If you add large image as tab bar item image you can adjust it's using following code.

for tabBarButton in self.tabBar.subviews{
        for badgeView in tabBarButton.subviews{
        var className=NSStringFromClass(badgeView.classForCoder)
            if  className == "_UIBadgeView"
            {
                badgeView.layer.transform = CATransform3DIdentity
                badgeView.layer.transform = CATransform3DMakeTranslation(-17.0, 1.0, 1.0)
            }
        }
    }


回答4:

In Objective-C:

    for (UIView *tabBarButton in self.navigationController.tabBarController.tabBar.subviews)
    {
        for (UIView *badgeView in tabBarButton.subviews)
        {
            NSString *className = NSStringFromClass([badgeView class]);

            // Looking for _UIBadgeView
            if ([className rangeOfString:@"BadgeView"].location != NSNotFound)
            {
                badgeView.layer.transform = CATransform3DIdentity;
                badgeView.layer.transform = CATransform3DMakeTranslation(-5.0, 1.0, 1.0);
            }
        }
    }


回答5:

In C# Xamarin

void RepositionBadge(int tab)
{
    foreach (var badgeView in TabBar.Subviews[tab].Subviews)
    {
        if (badgeView.Class.Name == "_UIBadgeView")
        {
            badgeView.Layer.Transform = CATransform3D.Identity;
            badgeView.Layer.Transform = CATransform3D.MakeTranslation(-10.0f, 1.0f, 1.0f);
        }
    }
}


回答6:

Swift 4, 5

I've created an extension for UITabBar which gets the badge view and the badge's label the swifty way:

extension UITabBar {
    func badgeViewForItem(at index: Int) -> UIView? {
        guard subviews.count > index else {
            return nil
        }
        return subviews[index].subviews.first(where: { NSStringFromClass($0.classForCoder) == "_UIBadgeView" })
    }

    func labelForItem(at index: Int) -> UILabel? {
        guard subviews.count > index else {
            return nil
        }
        return badgeViewForItem(at: index)?.subviews.first(where: { $0 is UILabel }) as? UILabel
    }
}

And then you can do something like:

let firstItemBadgeView = badgeViewForItem(at: 0)!
// Do something with the badge view like setting the border, background color ...
// ex: firstItemBadgeView.backgroundColor = UIColor.clear