web-dev-qa-db-fra.com

Est-il possible de changer la couleur du badge UITabBarItem

Je veux changer la couleur d'arrière-plan de UITabBarItembadge mais je ne trouve aucune ressource sur la façon de le faire.

enter image description here

30
1110

UITabBarItem est disponible depuis iOS 10.

var badgeColor: UIColor? { get set }

Il est également disponible via l'apparence.

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

documents de référence: https://developer.Apple.com/reference/uikit/uitabbaritem/1648567-badgecolor

29
Nuno Gonçalves

La modification de la couleur du badge est désormais prise en charge de manière native dans iOS 10 et versions ultérieures à l'aide de la propriété badgeColor dans votre UITabBarItem. Voir Apple docs pour plus d'informations sur la propriété.

Exemple:

  • Swift 3: myTab.badgeColor = UIColor.blue
  • Objectif c: [myTab setBadgeColor:[UIColor blueColor]];
13
Hans Knöchel

J'ai écrit ce morceau de code pour mon application, mais je ne l'ai testé que sur 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];
                }
            }
        }
    }
}

Vous ne pouvez mettre à jour l'arrière-plan du badge qu'avec une image, pas une couleur. J'ai également dévoilé l'étiquette du badge si vous souhaitez la mettre à jour d'une manière ou d'une autre.

Il est important de noter que ce code doit être appelé après avoir défini le tabBarItem.badgeValue!

EDIT: 4/14/14

Le code ci-dessus fonctionnera dans iOS 7 lorsqu'il sera appelé n'importe où. Pour le faire fonctionner dans iOS 7.1, appelez-le dans les contrôleurs de vue -viewWillLayoutSubviews.

EDIT: 22/12/14

Voici un extrait mis à jour que j'utilise actuellement. J'ai mis le code dans une extension de catégorie pour plus de simplicité.

- (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);
                }
            }
        }
    }
}

Ensuite, lorsque vous serez prêt à l'appeler, cela ressemblera à ceci.

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

}];

EDIT: 16/11/15

Il a été porté à mon attention que certaines personnes ont besoin d'un peu plus de clarté sur ce qui se passe dans ce code. Les boucles for recherchent quelques vues qui ne sont pas accessibles au public. En vérifiant si le nom de la classe de vues contient une partie du nom attendu, cela garantit d'atteindre la vue souhaitée tout en ne déclenchant aucun drapeau rouge possible par Apple. Une fois que tout a été localisé, un bloc est exécuté avec un accès facile à ces vues.

Il est à noter qu'il est possible que ce code cesse de fonctionner dans une future mise à jour iOS. Par exemple, ces vues internes pourraient un jour acquérir des noms de classe différents. Cependant, les chances de cela sont quasi nulles, car même en interne Apple refactorise rarement les classes de cette nature. Mais même si c'était le cas, ce serait quelque chose dans le titre de UITabBarBadgeView , qui atteindrait toujours le point attendu dans le code. Étant donné qu'iOS9 est bien sorti et que ce code fonctionne toujours comme prévu, vous pouvez vous attendre à ce que ce problème ne se pose jamais.

12
cnotethegr8

J'ai le même problème et je l'ai résolu en créant une petite catégorie qui remplace le BadgeView par un UILabel que vous pouvez personnaliser facilement.

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

10
eold

Pour les personnes utilisant Swift, j'ai réussi à améliorer la réponse de TimWhiting afin que la vue du badge fonctionne sur n'importe quelle taille d'écran et n'importe quelle orientation.

 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 {}
10
Kirualex

Swift Voici une version mise à jour de la réponse de @ Kirualex (qui a amélioré la réponse de @ TimWhiting) pour Swift 3.

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 {}
7

Non, vous ne pouvez pas changer la couleur mais vous pouvez utiliser vos propres badges à la place. Ajoutez cette extension à la portée du fichier et vous pouvez personnaliser les badges comme vous le souhaitez. Appelez simplement self.tabBarController!.setBadges([1,0,2]) dans l'un de vos contrôleurs de vue racine.

Pour être clair, c'est pour une barre d'onglets avec trois éléments, avec les valeurs de badge allant de gauche à droite.

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 {

}
7
TimWhiting

Il semble que non. Vous ne pouvez définir que la valeur. Du badge de documentation d'Apple est:

Texte affiché dans le coin supérieur droit de l'élément avec un ovale rouge.

4
RomanN

Vous devez spécifier l'élément d'onglet à l'index pour changer la couleur du badge, # disponible dans iOS 10,

    if #available(iOS 10.0, *) 
    {
        self.kAppTabBarController.tabBar.items![1].badgeColor = YOUR_COLOR
    }
1
Parimal

Vous pouvez maintenant le faire également dans le storyboard, en sélectionnant votre élément de barre d'onglets et en allant à l'inspecteur d'attributs.

enter image description here

0
Myxtic

OUI, mais la seule solution possible est de créer une barre de tabulation personnalisée et de créer votre icône de badge de barre de tabulation personnalisée. Vous trouverez de nombreux articles/codes pour créer une barre d'onglets personnalisée.

0
JiteshW
// 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];
                    }
                }
            }
        }
    }
}

enter image description here

0
Sargis Gevorgyan