web-dev-qa-db-fra.com

Couleur UITabBar non sélectionnée?

J'ai un UITabBar avec 5 éléments. Je souhaite modifier la couleur non sélectionnée de tous les éléments. Les éléments ne sont pas déclarés dans les classes UIViewController (je les ai construits et lié les vues dans le Storyboard).

Existe-t-il un code comme celui-ci: [[UITabBar appearance] set***UN***SelectedImageTintColor:[UIColor whiteColor]];?

50
user1530090

SO dit que je ne peux pas supprimer la réponse acceptée (j'ai essayé), mais il est évident qu'il existe de nombreux votes positifs pour les commentaires indiquant que cela ne fonctionne pas pour iOS 7.

Voir l'autre réponse ci-dessous avec de nombreux autres votes positifs, ou le lien dans le commentaire de @ Liam vers cette réponse.


pour iOS 6 uniquement

Cela devrait être aussi simple que cela:

[[UITabBar appearance] setTintColor:[UIColor grayColor]]; // for unselected items that are gray
[[UITabBar appearance] setSelectedImageTintColor:[UIColor greenColor]]; // for selected items that are green
18
john.k.doe

Cela ne fonctionnera pas sous iOS 7 pour autant que je puisse le dire. En particulier, tintColor de la barre d’onglet définira la couleur de l’onglet sélectionné , et non de ceux qui n’ont pas été sélectionnés. Si vous souhaitez modifier la valeur par défaut dans iOS 7, il semble que vous deviez utiliser différentes icônes (dans la couleur que vous préférez pour les onglets non sélectionnés) et définir la couleur du texte.

Cet exemple doit colorer les onglets sélectionnés en rouge et rendre les autres en vert. Exécutez ce code dans votre TabBarController:

// set color of selected icons and text to red
self.tabBar.tintColor = [UIColor redColor];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor redColor], NSForegroundColorAttributeName, nil] forState:UIControlStateSelected];


// set color of unselected text to green
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor greenColor], NSForegroundColorAttributeName, nil]
                                         forState:UIControlStateNormal];

// set selected and unselected icons
UITabBarItem *item0 = [self.tabBar.items objectAtIndex:0];

// this way, the icon gets rendered as it is (thus, it needs to be green in this example)
item0.image = [[UIImage imageNamed:@"unselected-icon.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

// this icon is used for selected tab and it will get tinted as defined in self.tabBar.tintColor
item0.selectedImage = [UIImage imageNamed:@"selected-icon.png"];

Si vous définissez l'icône dans le scénario uniquement, vous pouvez uniquement contrôler la couleur de l'onglet sélectionné (teinteCouleur). Toutes les autres icônes et le texte correspondant seront dessinés en gris. 

Peut-être que quelqu'un connaît un moyen plus simple d'adopter les couleurs sous iOS 7?

96
Sven Tiffe

En étendant la réponse de @Sven Tiffe pour iOS 7, vous pouvez obtenir que votre code teinte automatiquement les images UITabBar non sélectionnées ajoutées au storyboard. L’approche suivante vous évitera de devoir créer deux jeux d’icônes (sélectionnés ou non sélectionnés) et de les charger par programme. Ajoutez la méthode category imageWithColor: (voir - Comment changer l’image tintColor dans iOS et WatchKit ) à votre projet, puis insérez ce qui suit dans votre méthode personnalisée UITabBarController viewDidLoad:

// set the selected colors
[self.tabBar setTintColor:[UIColor whiteColor]];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor whiteColor], NSForegroundColorAttributeName, nil] forState:UIControlStateSelected];


UIColor * unselectedColor = [UIColor colorWithRed:184/255.0f green:224/255.0f blue:242/255.0f alpha:1.0f];

// set color of unselected text
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:unselectedColor, NSForegroundColorAttributeName, nil]
                                         forState:UIControlStateNormal];

// generate a tinted unselected image based on image passed via the storyboard
for(UITabBarItem *item in self.tabBar.items) {
    // use the UIImage category code for the imageWithColor: method
    item.image = [[item.selectedImage imageWithColor:unselectedColor] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}

Créez une catégorie appelée UIImage + Overlay et sur UIImage + Overlay.m (extraite de cette réponse ):

@implementation UIImage(Overlay)

- (UIImage *)imageWithColor:(UIColor *)color1
{
        UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(context, 0, self.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextSetBlendMode(context, kCGBlendModeNormal);
        CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
        CGContextClipToMask(context, rect, self.CGImage);
        [color1 setFill];
        CGContextFillRect(context, rect);
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
}
@end
68
user3719695

Dans iOS 10 et versions ultérieures, il existe 3 solutions simples possibles:

A. Instance du code (Swift):

self.tabBar.unselectedItemTintColor = unselectedcolor

B. Instance de IB:

Ajouter un chemin de clé: unselectedItemTintColor de type: Color

C. Apparence globale (rapide):

UITabBar.appearance().unselectedItemTintColor = unselectedcolor

 

64
vtcajones

Traduire la réponse de user3719695 en Swift, qui utilise désormais des extensions:

UIImage + Overlay.Swift

extension UIImage {
  func imageWithColor(color1: UIColor) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
    color1.setFill()

    let context = UIGraphicsGetCurrentContext()
    CGContextTranslateCTM(context, 0, self.size.height)
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextSetBlendMode(context, CGBlendMode.Normal)

    let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
    CGContextClipToMask(context, rect, self.CGImage)
    CGContextFillRect(context, rect)

    let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage
    UIGraphicsEndImageContext()

    return newImage
  }
}

customTabBar.Swift

override func viewDidLoad() {
  super.viewDidLoad()
  for item in self.tabBar.items! {
    item.image = item.selectedImage?.imageWithColor(unselectedColor).imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
    //In case you wish to change the font color as well
    let attributes = [NSForegroundColorAttributeName: unselectedColor]
    item.setTitleTextAttributes(attributes, forState: UIControlState.Normal)
  }
}
16
JoeGalind

Version Swift sous iOS 10 et supérieur -

UITabBar.appearance().tintColor = UIColor.gray
UITabBar.appearance().unselectedItemTintColor = UIColor.gray
11
Abhishek Jain

J'ai dû déplacer le code dans viewWillAppear car dans viewDidLoad, les images n'étaient pas encore définies.

Swift 4 Translation

import Foundation
import UIKit

extension UIImage {
    func with(color: UIColor) -> UIImage {
        guard let cgImage = self.cgImage else {
            return self
        }
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        let context = UIGraphicsGetCurrentContext()!
        context.translateBy(x: 0, y: size.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.setBlendMode(.normal)
        let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        context.clip(to: imageRect, mask: cgImage)
        color.setFill()
        context.fill(imageRect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext();
        return newImage
    }
}

class MYTabBarController: UITabBarController {

    let unselectedColor = UIColor(red: 108/255.0, green: 110/255.0, blue: 114/255.0, alpha: 1.0)
    let selectedColor = UIColor.blue()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Unselected state colors
        for item in self.tabBar.items! {
            item.image = item.selectedImage!.with(color: unselectedColor).withRenderingMode(.alwaysOriginal)
        }
        UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor : unselectedColor], for: .normal)

        // Selected state colors
        tabBar.tintColor = selectedColor
        UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor : selectedColor], for: .selected)
    }
}
6
kgaidis

En se référant à la réponse d'ici: Teinte UITabBar dans iOS 7

Vous pouvez définir la couleur de teinte pour les boutons de barre d’onglet sélectionnés et non sélectionnés comme suit:

[[UIView appearanceWhenContainedIn:[UITabBar class], nil] setTintColor:[UIColor redColor]];
[[UITabBar appearance] setSelectedImageTintColor:[UIColor greenColor]];

La première ligne définit la couleur non sélectionnée - rouge dans cet exemple - en définissant la teinteCouleur de UIView lorsqu'elle est contenue dans une barre de tabulation. Notez que ceci ne définit que la couleur de teinte de l'image non sélectionnée - cela ne change pas la couleur du texte situé en dessous.

La deuxième ligne définit la couleur de teinte de l'image sélectionnée sur la barre d'onglets en vert.

1
Benkax

La nouvelle solution pour effectuer cela par programme à partir de iOS 10+ consiste à utiliser l'API unselectedItemTintColor . Par exemple, si vous avez initialisé votre contrôleur de barre d'onglets dans votre AppDelegate, il ressemblerait à ceci:

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        ...

        let firstViewController = VC1()
        let secondViewController = VC2()
        let thirdViewController = VC3()


        let tabBarCtrl = UITabBarController()
        tabBarCtrl.viewControllers = [firstViewController, secondViewController, thirdViewController]

        // set the color of the active tab
        tabBarCtrl.tabBar.tintColor = UIColor.white

        // set the color of the inactive tabs
        tabBarCtrl.tabBar.unselectedItemTintColor = UIColor.gray

        ...
    }
1
Anchor

Version Swift 4 (sans ouvrir implicitement les options): 

UIImage + Overlay.Swift

import UIKit

extension UIImage {
    func with(color: UIColor) -> UIImage? {
        guard let cgImage = self.cgImage else {
            return self
        }
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        if let context = UIGraphicsGetCurrentContext() {
            context.translateBy(x: 0, y: size.height)
            context.scaleBy(x: 1.0, y: -1.0)
            context.setBlendMode(.normal)
            let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
            context.clip(to: imageRect, mask: cgImage)
            color.setFill()
            context.fill(imageRect)
            if let newImage = UIGraphicsGetImageFromCurrentImageContext() {
                UIGraphicsEndImageContext();
                return newImage
            }
        }
        return nil;
    }
}


CustomTabBarController.Swift

class CustomTabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        if #available(iOS 10.0, *) {
            self.tabBar.unselectedItemTintColor = UIColor.init(white: 1, alpha: 0.5)
        } else {
            // Fallback on earlier versions
            if let items = self.tabBar.items {
                let unselectedColor = UIColor.init(white: 1, alpha: 0.5)
                let selectedColor = UIColor.white
                // Unselected state colors
                for item in items {
                    if let selectedImage = item.selectedImage?.with(color: unselectedColor)?.withRenderingMode(.alwaysOriginal) {
                        item.image = selectedImage
                    }
                }
                UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor : unselectedColor], for: .normal)

                // Selected state colors
                tabBar.tintColor = selectedColor
                UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor : selectedColor], for: .selected)
            }
        }

        UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "overpass-light", size: 12)!, NSAttributedStringKey.foregroundColor: UIColor.white], for: UIControlState.normal)
    }
}
1
AhmedZah

Ou simplement sans coder. Swift 4, Xcode 10.1.

  1. Ajoutez UITabBar sur votre contrôleur View à l’aide de Interface Builder.
  2. Sélectionnez la vue ajoutée dans le panneau de gauche.
  3. Tapez cmd + alt + 3 ou cliquez simplement sur Show the Identity Inspector dans le panneau de droite.
  4. Dans la section User Defined Runtime Attributes, cliquez sur le bouton plus pour ajouter un nouvel attribut et appelez-le sous la forme unselectedItemTintColor (voir ici ).
  5. Sans quitter la section de l'étape précédente (voir numéro 4) dans la colonne Type, choisissez Color type.
  6. Enfin, définissez la couleur nécessaire dans la section Value.
  7. Compilez votre projet
  8. Plus de. Toutes nos félicitations. ????????

 enter image description here

0
Ivan Shokurov

La solution imageWithColor: de JoeGalid avec Xamarin:

using CoreGraphics;
using UIKit;

namespace Example
{
    public static class UIImageExtensions
    {
        public static UIImage ImageWithColor(this UIImage image, UIColor color)
        {
            UIGraphics.BeginImageContextWithOptions(image.Size, false, image.CurrentScale);

            color.SetFill();

            var context = UIGraphics.GetCurrentContext();

            context.TranslateCTM(0, image.Size.Height);
            context.ScaleCTM(1.0f, -1.0f);
            context.SetBlendMode(CoreGraphics.CGBlendMode.Normal);

            var rect = new CGRect(0, 0, image.Size.Width, image.Size.Height);
            context.ClipToMask(rect, image.CGImage);
            context.FillRect(rect);

            var newImage = UIGraphics.GetImageFromCurrentImageContext() as UIImage;
            UIGraphics.EndImageContext();

            return newImage;
        }
    }
}

Ensuite, utilisez-le pour configurer les éléments de la barre d'onglets:

var image = UIImage.FromBundle("name");
barItem.Image = image.ImageWithColor(UIColor.Gray).ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
barItem.SelectedImage = image.ImageWithColor(UIColor.Red).ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
0
JAM