web-dev-qa-db-fra.com

Teinte Couleur UIButton Image

J'ai remarqué que lorsque je place une UIImage blanche ou noire dans une UISegmentedControl, la couleur la masque automatiquement pour qu'elle corresponde à la teinte du contrôle segmenté. Je pensais que c'était vraiment cool et je me demandais si je pouvais le faire ailleurs. Par exemple, j'ai un tas de boutons qui ont une forme uniforme mais des couleurs variées. Au lieu de créer un fichier PNG pour chaque bouton, puis-je utiliser ce masquage de couleur pour utiliser la même image pour tous, mais définir ensuite une couleur ou une couleur pour modifier leur couleur réelle?

238
Logan Shire

Depuis iOS 7, il existe une nouvelle méthode sur UIImage pour spécifier le mode de rendu. L'utilisation du mode de rendu UIImageRenderingModeAlwaysTemplate permettra à la couleur de l'image d'être contrôlée par la couleur de teinte du bouton.

Objectif c

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *image = [[UIImage imageNamed:@"image_name"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[button setImage:image forState:UIControlStateNormal]; 
button.tintColor = [UIColor redColor];

Rapide

let button = UIButton(type: .custom)
let image = UIImage(named: "image_name")?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.red
524
Ric Santos

Comme Ric l'a déjà mentionné dans son post , vous pouvez définir le mode de rendu en code, vous pouvez également le faire directement dans le catalogue d'images, voir l'image ci-jointe ci-dessous. Il suffit de définir le Render As à Template Image

enter image description here

Avertissement J'ai eu des problèmes avec iOS 7 et cette approche. Donc, si vous utilisez également iOS 7, vous pouvez également le faire en code pour en être sûr, comme décrit ici .

203
hashier

Les boutons personnalisés apparaissent dans leurs couleurs respectives. Définir le type de bouton sur "Système" dans le storyboard (ou sur UIButtonTypeSystem dans le code) rendra l'image du bouton avec la couleur de teinte par défaut.

 Button Type System Renders Icons tinted

(testé sur iOS9, Xcode 7.3)

68
auco

Vous devez définir le mode de rendu de l'image sur UIImageRenderingModeAlwaysTemplate pour que tintColor affecte le paramètre UIImage. Voici la solution dans Swift:

let image = UIImage(named: "image-name")
let button = UIButton()
button.setImage(image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), forState: .Normal)
button.tintColor = UIColor.whiteColor()
35
Nick Wargnier

Si vous avez un bouton personnalisé avec une image d’arrière-plan. Vous pouvez définir la couleur de teinte de votre bouton et remplacer l’image par ce qui suit.

Dans les ressources, sélectionnez l’arrière-plan du bouton pour lequel vous souhaitez définir la couleur de teinte.

Dans l'inspecteur d'attributs de l'image, définissez la valeur du rendu sous "Modèle".

 enter image description here

Maintenant, chaque fois que vous définissezbutton.tintColor = UIColor.red, votre bouton apparaît en rouge. 

23
Ilker Baltaci

Dans Swift, vous pouvez le faire comme suit:

var exampleImage = UIImage(named: "ExampleImage.png")?.imageWithRenderingMode(.AlwaysTemplate)

Puis dans votre viewDidLoad

exampleButtonOutlet.setImage(exampleImage, forState: UIControlState.Normal)

Et pour modifier la couleur

exampleButtonOutlet.tintColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1) //your color

EDIT Xcode 8 Maintenant, vous pouvez aussi choisir le mode de rendu de l’image dans votre .xcassets vers un modèle d’image sans avoir à le déclarer spécifiquement dans le var exampleImage

17
Fri3ndlyGerman

Vous ne savez pas exactement ce que vous voulez, mais cette méthode de catégorie masquera une UIImage avec une couleur spécifiée afin que vous puissiez avoir une seule image et changer sa couleur comme vous voulez.

ImageUtils.h

- (UIImage *) maskWithColor:(UIColor *)color;

ImageUtils.m

-(UIImage *) maskWithColor:(UIColor *)color 
{
    CGImageRef maskImage = self.CGImage;
    CGFloat width = self.size.width;
    CGFloat height = self.size.height;
    CGRect bounds = CGRectMake(0,0,width,height);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, width, height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
    CGContextClipToMask(bitmapContext, bounds, maskImage);
    CGContextSetFillColorWithColor(bitmapContext, color.CGColor);    
    CGContextFillRect(bitmapContext, bounds);

    CGImageRef cImage = CGBitmapContextCreateImage(bitmapContext);
    UIImage *coloredImage = [UIImage imageWithCGImage:cImage];

    CGContextRelease(bitmapContext);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cImage);

    return coloredImage;    
}

Importez la catégorie ImageUtils et faites quelque chose comme ça ...

#import "ImageUtils.h"

...

UIImage *icon = [UIImage imageNamed:ICON_IMAGE];

UIImage *redIcon = [icon maskWithColor:UIColor.redColor];
UIImage *blueIcon = [icon maskWithColor:UIColor.blueColor];
14
Kirby Todd

Swift 4 avec customType: 

let button = UIButton(frame: aRectHere)
    let buttonImage = UIImage(named: "imageName")
    button.setImage(buttonImage?.withRenderingMode(.alwaysTemplate), for: .normal)
    button.tintColor = .white
7
aBikis

Swift 3:

Cette solution pourrait être confortable si vous avez déjà défini votre image via le constructeur d'interface xCode. En gros, vous avez une extension pour coloriser une image:

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

Ensuite, vous pouvez préparer cette extension UIButton pour coloriser l’image dans un état particulier:

extension UIButton {
    func imageWith(color:UIColor, for: UIControlState) {
        if let imageForState = self.image(for: state) {
            self.image(for: .normal)?.withRenderingMode(.alwaysTemplate)
            let colorizedImage = imageForState.image(withTintColor: color)
            self.setImage(colorizedImage, for: state)
        }
    }
}

Utilisation:

myButton.imageWith(.red, for: .normal)

P.S. (fonctionne bien aussi dans les cellules de tableau, vous n'avez pas besoin d'appeler la méthode setNeedDisplay(), le changement de couleur est immédiat en raison de l'extension UIImage ..

4
Alessandro Ornano

Pour Xamarin.iOS (C #):

        UIButton messagesButton = new UIButton(UIButtonType.Custom);
        UIImage icon = UIImage.FromBundle("Images/icon.png");
        messagesButton.SetImage(icon.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), UIControlState.Normal);
        messagesButton.TintColor = UIColor.White;
        messagesButton.Frame = new RectangleF(0, 0, 25, 25);
4

Si vous souhaitez masquer manuellement votre image, voici le code mis à jour qui fonctionne avec les écrans de rétine

- (UIImage *)maskWithColor:(UIColor *)color
{
    CGImageRef maskImage = self.CGImage;
    CGFloat width = self.size.width * self.scale;
    CGFloat height = self.size.height * self.scale;
    CGRect bounds = CGRectMake(0,0,width,height);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, width, height, 8, 0, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);
    CGContextClipToMask(bitmapContext, bounds, maskImage);
    CGContextSetFillColorWithColor(bitmapContext, color.CGColor);
    CGContextFillRect(bitmapContext, bounds);

    CGImageRef cImage = CGBitmapContextCreateImage(bitmapContext);
    UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:self.scale orientation:self.imageOrientation];

    CGContextRelease(bitmapContext);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cImage);

    return coloredImage;
}
3
Josh Bernfeld

Tu devrais essayer

Après avoir défini le cadre 

NSArray *arr10 =[NSArray arrayWithObjects:btn1,btn2,nil];
for(UIButton *btn10 in arr10)
{
CAGradientLayer *btnGradient2 = [CAGradientLayer layer];
btnGradient2.frame = btn10.bounds;

btnGradient2.colors = [NSArray arrayWithObjects:
                       (id)[[UIColor colorWithRed:151.0/255.0f green:206.0/255.5 blue:99.0/255.0 alpha:1] CGColor],
                       (id)[[UIColor colorWithRed:126.0/255.0f green:192.0/255.5 blue:65.0/255.0 alpha:1]CGColor],
                       nil];
[btn10.layer insertSublayer:btnGradient2 atIndex:0];

}
2
guptha

Swift 3.0

    let image = UIImage(named:"NoConnection")!

 warningButton = UIButton(type: .system)        
    warningButton.setImage(image, for: .normal)
    warningButton.tintColor = UIColor.lightText
    warningButton.frame = CGRect(Origin: CGPoint(x:-100,y:0), size: CGSize(width: 59, height: 56))

    self.addSubview(warningButton)
1
Jad

Changer l'image du bouton ou la couleur de la teinte de l'image, Swift:

btn.imageView?.image = btn.imageView?.image?.withRenderingMode(.alwaysTemplate)

btn.imageView?.tintColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
1
Urvish Modi

Aucune de ces solutions ne fonctionnait pour moi, car la teinte était effacée après un clic. Je devais utiliser

button.setImageTintColor(Palette.darkGray(), for: UIControlState())
0
Szymon Klimaszewski