web-dev-qa-db-fra.com

Création d'une UIImage à partir d'une UIColor à utiliser comme image d'arrière-plan 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 ensuite l'utiliser comme image de fond d'un bouton:

[resultButton setBackgroundImage:img forState:UIControlStateNormal];

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

Qu'est-ce que je rate?

151
Thorsten

J'ai créé une catégorie autour de UIButton pour pouvoir définir la couleur d'arrière-plan du bouton et définir l'état. Vous pourriez trouver cela 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 je lance en sourcing ouvert 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!
    }
}

Utilisé comme

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

Solution Xamarin.iOS

 public UIImage CreateImageFromColor()
 {
     var imageSize = new CGSize(30, 30);
     var imageSizeRectF = new CGRect(0, 0, 30, 30);
     UIGraphics.BeginImageContextWithOptions(imageSize, false, 0);
     var context = UIGraphics.GetCurrentContext();
     var red = new CGColor(255, 0, 0);
     context.SetFillColor(red);
     context.FillRect(imageSizeRectF);
     var image = UIGraphics.GetImageFromCurrentImageContext();
     UIGraphics.EndImageContext();
     return image;
 }
11
ben

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

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

Vous pouvez en savoir plus sur ce cas précis sur cet article sur UIColor et les durées de vie ARC ou obtenir plus de détails sur le objc_precise_lifetime attribut .

5
Jesse Rusak

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.

4
iGerm

Je suppose que 255 en 227./255 est perçu comme un entier et que la division est toujours un retour 0

3
aknew

Votre code fonctionne bien. Vous pouvez vérifier les couleurs RVB avec xScope d'Iconfactory . Il suffit de le comparer à [UIColor whiteColor].

3
bdunagan
CGContextSetFillColorWithColor(context,[[UIColor colorWithRed:(255/255.f) green:(0/255.f) blue: (0/255.f) alpha:1] CGColor]);
3
Muzamil Hassan