2013-01-24 1 views
6

Je travaille sur une application - ou plutôt sur un «framework» réutilisable que je suis heureux de partager une fois qu'il fonctionne. Dans cette application, l'utilisateur devrait être en mesure de choisir parmi une liste de thèmes de couleur. Par conséquent, l'application doit être capable de colorer ses éléments d'interface utilisateur d'une manière plutôt dynamique.Comment faire pour colorer les images d'arrière-plan d'un UIButton par programmation et dynamiquement?

Pour les boutons, toutes les teintes ne fonctionnent pas. Des images d'arrière-plan correctement teintées doivent être fournies ici. Mais préparer un ensemble d'images de fond pour chacun d'eux est juste le deuxième meilleur. Ce n'est pas assez dynamique et flexible. En fin de compte, une solution peut consister à fournir une image dégradée monochrome (grise) pour l'état sélectionné et normal et à colorier cette image par programmation avec CoreGraphics ou OpenGL. Mais franchement, je ne sais pas par où commencer. A quoi devrait ressembler le dégradé et comment le coloriser par programme dans une couleur donnée?

Cela s'applique à UISegmentedControls, un peu plus compliqué. :) Toute solution générique qui couvre UISegementedControls aussi est grandement appréciée.

+0

Jetez un oeil à [GMButton] (https://github.com/progrmr/SDK_Utilities/blob/master/GM_Subclasses/GMButton.h) . Il vous permet de définir des couleurs pour tous les états des boutons et fournit également des dégradés de biseau et de brillant. – progrmr

+0

On dirait bien ce que vous avez fait là-bas. Il semble que j'ai juste besoin d'adopter ceci à ARC et alors il devrait faire tout ce que je veux. Merci. –

Répondre

12

J'ai fait une catégorie UIImage suivant un autre poste que je ne peux pas trouver qui prend l'image et teintes comme suit:

- (UIImage *)tintedImageWithColor:(UIColor *)tintColor { 
    UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 


    CGContextTranslateCTM(context, 0, self.size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 

    CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height); 

    // draw alpha-mask 
    CGContextSetBlendMode(context, kCGBlendModeNormal); 
    CGContextDrawImage(context, rect, self.CGImage); 

    // draw tint color, preserving alpha values of original image 
    CGContextSetBlendMode(context, kCGBlendModeSourceIn); 
    [tintColor setFill]; 
    CGContextFillRect(context, rect); 

    UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return coloredImage; 
} 

Cela prendra l'image et remplira toutes les zones avec une valeur alpha avec la couleur donnée.

+0

Travaillez comme un chram! –

0

Je vous renvoie à une question SO qui semble être ce que vous cherchez et elle a une réponse.

How to tint a transparent PNG image in iPhone?

Bonne chance!

Juste un petit détail sur votre rubrique rubrique ... vous voulez dire "Comment" et non "Hot" Droit?

+1

Ce n'était pas la réponse que j'espérais, mais cela semble faisable. Merci. Je vais essayer, probablement le week-end. –

1

Voici une réponse partielle à votre question. Ceci est une méthode d'assistance que j'ai écrit que les teintes d'une image d'échelle de gris:

// baseImage is the grey scale image. color is the desired tint color 
+ (UIImage *)tintImage:(UIImage *)baseImage withColor:(UIColor *)color { 
    UIGraphicsBeginImageContextWithOptions(baseImage.size, NO, baseImage.scale); 

    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    CGRect area = CGRectMake(0, 0, baseImage.size.width, baseImage.size.height); 

    CGContextScaleCTM(ctx, 1, -1); 
    CGContextTranslateCTM(ctx, 0, -area.size.height); 

    CGContextSaveGState(ctx); 
    CGContextClipToMask(ctx, area, baseImage.CGImage); 

    [color set]; 
    CGContextFillRect(ctx, area); 
    CGContextRestoreGState(ctx); 

    CGContextSetBlendMode(ctx, kCGBlendModeOverlay); 

    CGContextDrawImage(ctx, area, baseImage.CGImage); 

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    // If the original image was stretchable, make the new image stretchable 
    if (baseImage.leftCapWidth || baseImage.topCapHeight) { 
     newImage = [newImage stretchableImageWithLeftCapWidth:baseImage.leftCapWidth topCapHeight:baseImage.topCapHeight]; 
    } 

    return newImage; 
} 
+0

Merci jusqu'à présent. Je vais essayer le week-end ou le début de la semaine prochaine. Il ressemble à l'essentiel de ce que @OnlyYou a lié. Bien que je ne sois pas familier avec le CG Graphics, il est assez explicite. Juste une question. Ce CGContextScalTCM et ContextTranslateTCM est pour la transformation de coordonnées car UIKit et CGGraphics ont des origines différentes et une orientation différente sur le y-axix? –

41

En vous pouvez utiliser iOS 7 la méthode imagedWithRenderingMode: conjointement avec la méthode setTintColor:

Mais, assurez-vous d'utiliser UIImageRenderingModeAlwaysTemplate car il remplace toutes les couleurs non transparentes sur un UIImage avec la couleur de teinte. La valeur par défaut est UIImageRenderingModeAutomatic.

UIImageRenderingModeAlwaysTemplate

Always draw the image as a template image, ignoring its color information. 

Exemple:

[myButton setTintColor:[UIColor colorWithRed:0 green:0.8196f blue:0.0039f alpha:1]]; 

    UIImage * image = [myButton.currentBackgroundImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 

    [myButton setBackgroundImage:image forState:UIControlStateNormal]; 
+1

Soyez prudent - Avoir le UIImage __weak ne montre aucune image sur le bouton dans les versions du mode de publication ios 9 –

+0

Travail pour SetImage pas pour SetBackgroudIamge –

4

J'ai créé une catégorie UIButton en utilisant le code de horsejockey: https://github.com/filipstefansson/UITintedButton

Voici les nouvelles méthodes:

-(void)setImageTintColor:(UIColor *)color; 
-(void)setBackgroundTintColor:(UIColor *)color forState:(UIControlState)state; 
+(void)tintButtonImages:(NSArray *)buttons withColor:(UIColor *)color; 
+(void)tintButtonBackgrounds:(NSArray *)buttons withColor:(UIColor *)color forState:(UIControlState)state; 
0

Je HABITATION certaines choses "horsejockey":

+(UIImage *)getTintedImage:(UIImage*)image withColor:(UIColor *)tintColor 
{ 
    UIGraphicsBeginImageContextWithOptions(image.size, NO, [[UIScreen mainScreen] scale]); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 


    CGContextTranslateCTM(context, 0, image.size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 

    CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); 

    // draw alpha-mask 
    CGContextSetBlendMode(context, kCGBlendModeNormal); 
    CGContextDrawImage(context, rect, image.CGImage); 

    // draw tint color, preserving alpha values of original image 
    CGContextSetBlendMode(context, kCGBlendModeSourceIn); 
    [tintColor setFill]; 
    CGContextFillRect(context, rect); 

    UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return coloredImage; 
}
Questions connexes