This improves the answer in the question and the @Anomie implementation
First put this at the beginning of your UIButton class or your view controller. It translates from UIColor to the RGBA value, which you will need later.
typedef enum { R, G, B, A } UIColorComponentIndices; @implementation UIColor (EPPZKit) - (CGFloat)redRGBAValue { return CGColorGetComponents(self.CGColor)[R]; } - (CGFloat)greenRGBAValue { return CGColorGetComponents(self.CGColor)[G]; } - (CGFloat)blueRGBAValue { return CGColorGetComponents(self.CGColor)[B]; } - (CGFloat)alphaRGBAValue { return CGColorGetComponents(self.CGColor)[A]; } @end
Now make sure you have a custom IB image button with a grayscale picture and a right frame. This is significantly better and easier than programmatically creating a custom image button, because:
- you can let IB upload the image, rather than upload it manually.
- you can customize the button and see it visually in IB
- your IB will be more like your application at runtime
- you do not need to set frames manually
Assuming you have a button in IB (next to it there will be support for its programmatic creation), add this method to your view controller or to the cub cub class:
- (UIImage*)customImageColoringFromButton:(UIButton*)customImageButton fromColor:(UIColor*)color { UIImage *customImage = [customImageButton.imageView.image copy]; UIGraphicsBeginImageContext(customImageButton.imageView.frame.size); { CGContextRef X = UIGraphicsGetCurrentContext(); [customImage drawInRect: customImageButton.imageView.frame]; // Overlay a colored rectangle CGContextSetBlendMode( X, kCGBlendModeColor) ; CGContextSetRGBFillColor ( X, color.redRGBAValue, color.greenRGBAValue, color.blueRGBAValue, color.alphaRGBAValue); CGContextFillRect ( X, customImageButton.imageView.frame); // Redraw [customImage drawInRect:customImageButton.imageView.frame blendMode: kCGBlendModeDestinationIn alpha: 1.0]; customImage = UIGraphicsGetImageFromCurrentImageContext(); } UIGraphicsEndImageContext(); return customImage; }
Then you will need to call it in the setup method in your view controller or subclass of the button and set the button image for it:
[myButton.imageView setImage:[self customImageColoringFromButton:myButton fromColor:desiredColor]];
If you are not using IB to create a button, use this method:
- (UIImage*)customImageColoringFromImage:(UIImage*)image fromColor:(UIColor*)color fromFrame:(CGRect)frame { UIImage *customImage = [image copy]; UIGraphicsBeginImageContext(frame.size); { CGContextRef X = UIGraphicsGetCurrentContext(); [customImage drawInRect: frame]; // Overlay a colored rectangle CGContextSetBlendMode( X, kCGBlendModeColor) ; CGContextSetRGBFillColor ( X, color.redRGBAValue, color.greenRGBAValue, color.blueRGBAValue, color.alphaRGBAValue); CGContextFillRect ( X, frame); // Redraw [customImage drawInRect:frame blendMode: kCGBlendModeDestinationIn alpha: 1.0]; customImage = UIGraphicsGetImageFromCurrentImageContext(); } UIGraphicsEndImageContext(); return customImage; }
And name it with:
[self.disclosureButton.imageView setImage:[self customImageColoringFromImage:[UIImage imageNamed:@"GemTop_Dull.png"] fromColor:desiredColor fromFrame:desiredFrame]];