155 votes

Création d'une UIImage à partir d'une UIColor pour l'utiliser comme image de fond pour UIButton

Je crée une image colorée comme ceci :

CGRect rect = CGRectMake(0, 0, 1, 1);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context,
                                   [[UIColor redColor] CGColor]);
//  [[UIColor colorWithRed:222./255 green:227./255 blue: 229./255 alpha:1] CGColor]) ;
CGContextFillRect(context, rect);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

et l'utiliser comme image d'arrière-plan d'un bouton :

[resultButton setBackgroundImage:img forState:UIControlStateNormal];

Cela fonctionne très bien en utilisant redColor, mais je veux utiliser une couleur RGB (comme indiqué dans la ligne commentée). Lorsque j'utilise la couleur RGB, l'arrière-plan des boutons n'est pas modifié.

Qu'est-ce que je rate ?

142voto

ScottWasserman Points 121

J'ai créé une catégorie autour de UIButton pour pouvoir définir la couleur de fond du bouton et définir son état. Cela pourrait vous être utile.

@implementation  UIButton (ButtonMagic)

- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state {
    [self setBackgroundImage:[UIButton imageFromColor:backgroundColor] forState:state];
}

+ (UIImage *)imageFromColor:(UIColor *)color {
    CGRect rect = CGRectMake(0, 0, 1, 1);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

Cela fera partie d'un ensemble de catégories d'aide que j'ouvrirai ce mois-ci.

Swift 2.2

extension UIImage {
static func fromColor(color: UIColor) -> UIImage {
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
    UIGraphicsBeginImageContext(rect.size)
    let context = UIGraphicsGetCurrentContext()
    CGContextSetFillColorWithColor(context, color.CGColor)
    CGContextFillRect(context, rect)
    let img = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return img
  }
}

Swift 3.0

extension UIImage {
    static func from(color: UIColor) -> UIImage {
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context!.setFillColor(color.cgColor)
        context!.fill(rect)
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img!
    }
}

Utiliser comme

let img = UIImage.from(color: .black)

126voto

Matt Logan Points 2116

Il vaut la peine de faire un UIImage avec la méthode de cette classe.

+ (UIImage *)imageWithColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

Il suffit ensuite d'importer la catégorie dans toute classe qui en a besoin.

6voto

Jesse Rusak Points 33702

Utilisez-vous l'ARC ? Le problème ici est que vous n'avez pas de référence à l'adresse de l'utilisateur. UIColor que vous essayez d'appliquer ; l'objet CGColor est soutenu par ce UIColor mais l'ARC désallouera le UIColor avant que vous n'ayez la chance d'utiliser le CGColor .

La solution la plus claire est d'avoir une variable locale pointant vers votre UIColor avec le objc_precise_lifetime attribut.

Vous pouvez lire plus sur ce cas précis sur cet article sur UIColor et les durées de vie courtes de l'ARC ou obtenir plus de détails sur le site objc_precise_lifetime attribut .

5voto

iGerm Points 45

Ajoutez les points à toutes les valeurs :

[[UIColor colorWithRed:222./255. green:227./255. blue: 229./255. alpha:1] CGColor]) ;

Sinon, vous divisez float par int.

4voto

aknew Points 799

Je suppose que 255 dans 227./255 est perçu comme un nombre entier et que la division renvoie toujours 0.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X