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.
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.
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.
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)
}
}
}
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);
}
}
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With