2011-06-27 10 views
129

estoy creando una imagen en color como esto:Creación de una UIImage de un UIColor utilizar como imagen de fondo para UIButton

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(); 

y luego usarlo como imagen de fondo de un botón como:

[resultButton setBackgroundImage:img forState:UIControlStateNormal]; 

Esto funciona muy bien con el color rojo, sin embargo, quiero utilizar un color RGB (como se muestra en la línea comentada). Cuando uso el color RGB, el fondo de los botones no cambia.

¿Qué me estoy perdiendo?

+0

Si solo está configurando un color de fondo para el botón, ¿por qué no usaría simplemente el método setBackgroundColor:? –

+0

Al configurar el fondoColor solo cambia el exterior de las esquinas redondeadas, pero no el área real del botón. – Thorsten

+0

Tu código funciona bien en mi ENV, xcode501, iPhoneSimulator703, fíjate bien, el botón probablemente sea un botón con una imagen blanca clara. – oxromantic

Respuesta

3

supongo que 255 en 227./255 se percibe como un entero y división es siempre devuelven 0

+0

Gracias por la idea (también sugerida por alguien que eliminó su respuesta). La división funciona bien tal como está, incluso cuando se construye el color de los flotadores correctamente establecidos (los dummy vars declarados y su valor comprobado en el depurador), configurar la imagen de fondo no hace nada. – Thorsten

3

Su código funciona bien. Puede verificar los colores RGB con Iconfactory's xScope. Simplemente compárelo con [UIColor whiteColor].

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

No estoy seguro de lo que quiere decir con su respuesta ... No intenté reemplazar colorRed con valores RGB, sino que usé mis propios valores, lo cual no parece funcionar. – Thorsten

5

¿Estás utilizando ARC? El problema aquí es que no tiene una referencia al objeto UIColor que está intentando aplicar; el CGColor está respaldado por ese UIColor, pero ARC desasignará el UIColor antes de que tenga la oportunidad de usar el CGColor.

La solución más clara es tener una variable local apuntando a su UIColor con el atributo objc_precise_lifetime.

Puede leer más sobre este caso en particular en this article about UIColor and short ARC lifetimes o puede obtener más detalles sobre the objc_precise_lifetime attribute.

+0

Una observación válida, pero que daría lugar a un bloqueo, que parece que el OP no ha observado. –

+0

No necesariamente; depende de los detalles de cómo CGColor y CGContextFillRect interactúan, sin mencionar otros detalles que pueden cambiar de la versión del sistema operativo a la versión del sistema operativo. Ciertamente podría ser otra cosa, pero dado que el código está roto como está escrito (si se usa ARC) es un primer paso al menos. –

+0

Mi código era de los días previos a ARC. – Thorsten

4

Añadir los puntos para todos los valores:

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

De lo contrario, estás dividiendo flotador por int.

+5

No es cierto: el argumento entero se promueve automáticamente a un valor de coma flotante (en este caso doble) antes de que se evalúe la expresión, porque el operando de la izquierda es de tipo double. [Vea esta respuesta para una explicación detallada] (http://stackoverflow.com/questions/5563000/implicit-type-conversion-rules-in-c-operators) –

104

Creé una categoría alrededor de UIButton para poder establecer el color de fondo del botón y establecer el estado. Puede encontrar esto útil.

@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; 
} 

Esto formará parte de un conjunto de categorías de ayuda Estoy abierto abastecimiento este mes.

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! 
    } 
} 

uso como solución

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

muchas gracias, amigo. – Felipe

+0

En lugar de ser una categoría en UIButton, aunque ahora en Swift estamos en extensiones en lugar de categorías, ¿no crees que sería mejor tener una extensión en UIImage para el inicializador en lugar de UIButton – SwiftMatt

+0

? Puedo usar esto para crear un imagen de ciertas dimensiones? ¿Cómo lo hago? Lo siento si mi pregunta parece muy ingenua ..: -/ – Shyam

7

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; 
} 
Cuestiones relacionadas