30

我想更改UITabBarItem 徽章的背景颜色,但找不到任何有关如何制作它的资源。

在此处输入图像描述

4

15 回答 15

40

UITabBarItem从 iOS 10 开始就有这个功能了。

var badgeColor: UIColor? { get set }

它也可以通过外观获得。

if #available(iOS 10, *) {
   UITabBarItem.appearance().badgeColor = .green
}

参考文档: https ://developer.apple.com/reference/uikit/uitabbaritem/1648567-badgecolor

于 2016-09-28T16:32:58.503 回答
17

iOS 10 和更高版本现在原生支持更改徽章颜色,badgeColor使用UITabBarItem. 有关该属性的更多信息,请参阅苹果文档

例子:

  • 斯威夫特 3:myTab.badgeColor = UIColor.blue
  • 目标-C:[myTab setBadgeColor:[UIColor blueColor]];
于 2016-08-29T22:39:49.733 回答
12

我为我的应用程序编写了这段代码,但我只在 iOS 7 中对其进行了测试。

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

        // looking for _UIBadgeView
        if ([className rangeOfString:@"BadgeView"].location != NSNotFound) {
            for (UIView* badgeSubview in badgeView.subviews) {
                NSString* className = NSStringFromClass([badgeSubview class]);

                // looking for _UIBadgeBackground
                if ([className rangeOfString:@"BadgeBackground"].location != NSNotFound) {
                    @try {
                        [badgeSubview setValue:[UIImage imageNamed:@"YourCustomImage.png"] forKey:@"image"];
                    }
                    @catch (NSException *exception) {}
                }

                if ([badgeSubview isKindOfClass:[UILabel class]]) {
                    ((UILabel *)badgeSubview).textColor = [UIColor greenColor];
                }
            }
        }
    }
}

您只能使用图像而不是颜色来更新徽章背景。如果您想以某种方式更新它,我还公开了徽章标签。

需要注意的是,此代码必须在设置后调用tabBarItem.badgeValue

编辑:2014 年 4 月 14 日

上面的代码在任何地方调用时都可以在 iOS 7 中运行。要让它在 iOS 7.1 中工作,请在视图控制器中调用它-viewWillLayoutSubviews

编辑:14 年 12 月 22 日

这是我目前正在使用的更新片段。为简单起见,我将代码放在类别扩展中。

- (void)badgeViews:(void (^)(UIView* badgeView, UILabel* badgeLabel, UIView* badgeBackground))block {
    if (block) {
        for (UIView* tabBarButton in self.subviews) {
            for (UIView* badgeView in tabBarButton.subviews) {
                NSString* className = NSStringFromClass([badgeView class]);

                if ([className rangeOfString:@"BadgeView"].location != NSNotFound) {
                    UILabel* badgeLabel;
                    UIView* badgeBackground;

                    for (UIView* badgeSubview in badgeView.subviews) {
                        NSString* className = NSStringFromClass([badgeSubview class]);

                        if ([badgeSubview isKindOfClass:[UILabel class]]) {
                            badgeLabel = (UILabel *)badgeSubview;

                        } else if ([className rangeOfString:@"BadgeBackground"].location != NSNotFound) {
                            badgeBackground = badgeSubview;
                        }
                    }

                    block(badgeView, badgeLabel, badgeBackground);
                }
            }
        }
    }
}

然后当你准备好调用它时,它看起来像这样。

[self.tabBar badgeViews:^(UIView *badgeView, UILabel *badgeLabel, UIView *badgeBackground) {

}];

编辑:11/16/15

我注意到有些人需要更清楚地了解这段代码中发生的事情。for 循环正在搜索一些不可公开访问的视图。通过检查视图类名称是否包含预期名称的一部分,可以确保到达预期视图,同时不会引发 Apple 的任何可能的危险信号。一旦找到所有内容,就可以轻松访问这些视图来执行一个块。

值得注意的是,此代码有可能在未来的 iOS 更新中停止工作。例如,这些内部视图有朝一日可能会获得不同的类名。然而,这种可能性几乎为零,因为即使在内部,Apple 也很少将类重构为这种性质。但即使他们这样做,它也将是类似标题的东西UITabBarBadgeView,它仍然会达到代码中的预期点。由于 iOS9 已经推出,而且这段代码仍在按预期工作,你可以期望这个问题永远不会出现。

于 2014-04-03T09:41:29.537 回答
10

我有同样的问题,并通过创建一个小类别将 BadgeView 替换为您可以轻松自定义的 UILabel 来解决它。

https://github.com/enryold/UITabBarItem-CustomBadge/

于 2014-05-18T16:18:42.143 回答
10

对于使用 Swift 的人,我设法改进了 TimWhiting 的答案,以使徽章视图可以在任何屏幕尺寸和任何方向上工作。

 extension UITabBarController {

    func setBadges(badgeValues: [Int]) {

        for view in self.tabBar.subviews {
            if view is CustomTabBadge {
                view.removeFromSuperview()
            }
        }

        for index in 0...badgeValues.count-1 {
            if badgeValues[index] != 0 {
                addBadge(index, value: badgeValues[index], color:UIColor(paletteItem: .Accent), font: UIFont(name: Constants.ThemeApp.regularFontName, size: 11)!)
            }
        }
    }

    func addBadge(index: Int, value: Int, color: UIColor, font: UIFont) {
        let badgeView = CustomTabBadge()

        badgeView.clipsToBounds = true
        badgeView.textColor = UIColor.whiteColor()
        badgeView.textAlignment = .Center
        badgeView.font = font
        badgeView.text = String(value)
        badgeView.backgroundColor = color
        badgeView.tag = index
        tabBar.addSubview(badgeView)

        self.positionBadges()
    }

    override public func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.positionBadges()
    }

    // Positioning
    func positionBadges() {

        var tabbarButtons = self.tabBar.subviews.filter { (view: UIView) -> Bool in
            return view.userInteractionEnabled // only UITabBarButton are userInteractionEnabled
        }

        tabbarButtons = tabbarButtons.sort({ $0.frame.origin.x < $1.frame.origin.x })

        for view in self.tabBar.subviews {
            if view is CustomTabBadge {
                let badgeView = view as! CustomTabBadge
                self.positionBadge(badgeView, items:tabbarButtons, index: badgeView.tag)
            }
        }
    }

    func positionBadge(badgeView: UIView, items: [UIView], index: Int) {

        let itemView = items[index]
        let center = itemView.center

        let xOffset: CGFloat = 12
        let yOffset: CGFloat = -14
        badgeView.frame.size = CGSizeMake(17, 17)
        badgeView.center = CGPointMake(center.x + xOffset, center.y + yOffset)
        badgeView.layer.cornerRadius = badgeView.bounds.width/2
        tabBar.bringSubviewToFront(badgeView)
    }
}

class CustomTabBadge: UILabel {}
于 2016-03-07T14:18:44.403 回答
7

Swift 3这是 Swift 3 的 @Kirualex 答案的更新版本(改进了 @TimWhiting 的答案)。

extension UITabBarController {

    func setBadges(badgeValues: [Int]) {

        for view in self.tabBar.subviews {
            if view is CustomTabBadge {
                view.removeFromSuperview()
            }
        }

        for index in 0...badgeValues.count-1 {
            if badgeValues[index] != 0 {
                addBadge(index: index, value: badgeValues[index], color: UIColor.blue, font: UIFont(name: "Helvetica-Light", size: 11)!)
            }
        }
    }

    func addBadge(index: Int, value: Int, color: UIColor, font: UIFont) {
        let badgeView = CustomTabBadge()

        badgeView.clipsToBounds = true
        badgeView.textColor = UIColor.white
        badgeView.textAlignment = .center
        badgeView.font = font
        badgeView.text = String(value)
        badgeView.backgroundColor = color
        badgeView.tag = index
        tabBar.addSubview(badgeView)

        self.positionBadges()
    }

    override open func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.positionBadges()
    }

    // Positioning
    func positionBadges() {

        var tabbarButtons = self.tabBar.subviews.filter { (view: UIView) -> Bool in
            return view.isUserInteractionEnabled // only UITabBarButton are userInteractionEnabled
        }

        tabbarButtons = tabbarButtons.sorted(by: { $0.frame.origin.x < $1.frame.origin.x })

        for view in self.tabBar.subviews {
            if view is CustomTabBadge {
                let badgeView = view as! CustomTabBadge
                self.positionBadge(badgeView: badgeView, items:tabbarButtons, index: badgeView.tag)
            }
        }
    }

    func positionBadge(badgeView: UIView, items: [UIView], index: Int) {

        let itemView = items[index]
        let center = itemView.center

        let xOffset: CGFloat = 12
        let yOffset: CGFloat = -14
        badgeView.frame.size = CGSize(width: 17, height: 17)
        badgeView.center = CGPoint(x: center.x + xOffset, y: center.y + yOffset)
        badgeView.layer.cornerRadius = badgeView.bounds.width/2
        tabBar.bringSubview(toFront: badgeView)
    }
}

class CustomTabBadge: UILabel {}
于 2017-01-26T15:22:32.917 回答
7

不,您不能更改颜色,但您可以使用自己的徽章。在文件范围内添加此扩展名,您可以根据需要自定义徽章。只需调用self.tabBarController!.setBadges([1,0,2])您的任何根视图控制器。

需要明确的是,这是一个包含三个项目的标签栏,徽章值从左到右。

extension UITabBarController {
    func setBadges(badgeValues:[Int]){

        var labelExistsForIndex = [Bool]()

        for value in badgeValues {
            labelExistsForIndex.append(false)
        }

        for view in self.tabBar.subviews {
            if view.isKindOfClass(PGTabBadge) {
                let badgeView = view as! PGTabBadge
                let index = badgeView.tag

                if badgeValues[index]==0 {
                    badgeView.removeFromSuperview()
                }

                labelExistsForIndex[index]=true
                badgeView.text = String(badgeValues[index])

            }
        }

        for var i=0;i<labelExistsForIndex.count;i++ {
            if labelExistsForIndex[i] == false {
                if badgeValues[i] > 0 {
                    addBadge(i, value: badgeValues[i], color:UIColor(red: 4/255, green: 110/255, blue: 188/255, alpha: 1), font: UIFont(name: "Helvetica-Light", size: 11)!)
                }
            }
        }


    }

    func addBadge(index:Int,value:Int, color:UIColor, font:UIFont){

        let itemPosition = CGFloat(index+1)
        let itemWidth:CGFloat = tabBar.frame.width / CGFloat(tabBar.items!.count)

        let bgColor = color

        let xOffset:CGFloat = 12
        let yOffset:CGFloat = -9

        var badgeView = PGTabBadge()
        badgeView.frame.size=CGSizeMake(17, 17)
        badgeView.center=CGPointMake((itemWidth * itemPosition)-(itemWidth/2)+xOffset, 20+yOffset)
        badgeView.layer.cornerRadius=badgeView.bounds.width/2
        badgeView.clipsToBounds=true
        badgeView.textColor=UIColor.whiteColor()
        badgeView.textAlignment = .Center
        badgeView.font = font
        badgeView.text = String(value)
        badgeView.backgroundColor = bgColor
        badgeView.tag=index
        tabBar.addSubview(badgeView)

    }
}

class PGTabBadge: UILabel {

}
于 2015-08-30T12:36:47.430 回答
4

看来没有。您只能设置该值。来自 Apple 的文档徽章是:

显示在项目右上角的文本,周围有一个红色椭圆。

于 2012-11-12T10:10:31.693 回答
1

您需要在索引处指定选项卡项以更改徽章颜色,#available in iOS 10 ,

    if #available(iOS 10.0, *) 
    {
        self.kAppTabBarController.tabBar.items![1].badgeColor = YOUR_COLOR
    }
于 2018-09-10T04:03:37.950 回答
1

您现在也可以在情节提要中执行此操作,方法是选择您的标签栏项目并转到属性检查器。

在此处输入图像描述

于 2019-07-17T11:27:50.347 回答
0

是的,但唯一可能的解决方案是创建自定义标签栏并创建自定义标签栏徽章图标。您会发现许多用于创建自定义标签栏的文章/代码。

于 2012-11-12T10:14:00.997 回答
0

嗯……很简单。[[self tabBarItem] setBadgeColor:[UIColor greenColor]];

于 2020-11-22T18:48:57.947 回答
0
// change TabBar BadgeView background Color
-(void)changeTabBarBadgeViewBgColor:(UITabBar*)tabBar {
    for (UIView* tabBarButton in tabBar.subviews) {
        for (UIView* badgeView in tabBarButton.subviews) {
            NSString* className = NSStringFromClass([badgeView class]);

            // looking for _UIBadgeView
            if ([className rangeOfString:@"BadgeView"].location != NSNotFound) {
                for (UIView* badgeSubview in badgeView.subviews) {
                    NSString* className = NSStringFromClass([badgeSubview class]);

                    // looking for _UIBadgeBackground
                    if ([className rangeOfString:@"BadgeBackground"].location != NSNotFound) {
                        @try {
                            [badgeSubview setValue:nil forKey:@"image"];
                            [badgeSubview setBackgroundColor:[UIColor blueColor]];
                            badgeSubview.clipsToBounds = YES;
                            badgeSubview.layer.cornerRadius = badgeSubview.frame.size.height/2;
                        }
                        @catch (NSException *exception) {}
                    }

                    if ([badgeSubview isKindOfClass:[UILabel class]]) {
                        ((UILabel *)badgeSubview).textColor = [UIColor greenColor];
                    }
                }
            }
        }
    }
}

在此处输入图像描述

于 2016-09-08T13:21:28.350 回答
0

由于 iOS 15 有不同的方法,所以在我的情况下有效:

let appearance = UITabBarAppearance()
appearance.configureWithTransparentBackground()
        
let barAppearance = UITabBarItemAppearance()
        
barAppearance.normal.badgeBackgroundColor = .green
barAppearance.normal.badgeTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.red]

appearance.stackedLayoutAppearance = barAppearance
     
tabBar.standardAppearance = appearance
于 2021-09-29T11:02:21.797 回答
-2

看看这里@ UITabbarItem-CustomBadge

下面是一个完整的演示

示范

如果要使用默认实现,只需要两行代码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  //supplying the animation parameter
  [UITabBarItem setDefaultAnimationProvider:[[DefaultTabbarBadgeAnimation alloc] init]];
  [UITabBarItem setDefaultConfigurationProvider:[[DefaultSystemLikeBadgeConfiguration alloc] init]];

  //rest of your code goes following...

  return YES;
}
于 2016-11-22T15:14:36.853 回答