Je veux changer la couleur d'arrière-plan de UITabBarItem
badge mais je ne trouve aucune ressource sur la façon de le faire.
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
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:
myTab.badgeColor = UIColor.blue
[myTab setBadgeColor:[UIColor blueColor]];
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.
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.
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 {}
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 {}
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 {
}
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.
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
}
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.
// 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];
}
}
}
}
}
}