I know similar question(s) have been asked before, but most answers say create a new detail disclosure button image with the required color (e.g. How to change color of detail disclosure button for table cell).
I want to be able to change it to any color I choose, dynamically, at run-time, so using a pre-configured image is not viable.
From reading around, I think there may be a few ways to do this, but I'm not sure which is the best, or exactly how to do it:
Draw the required color circle in code and overlay with an image of shadow round outside of circle and arrow right (with clear alpha channel for rest, so drawn color circle is still visible)
Add image of shadow round outside of circle in UIImageView, and using as a mask, flood fill within this shadow circle, then overlay the arrow.
Add greyscale image, mask it with itself, and overlay the required color (e.g. http://coffeeshopped.com/2010/09/iphone-how-to-dynamically-color-a-uiimage), then overlay that with arrow image.
What is the best way, and does anyone have any code showing exactly how to do it ?
I use the following helper method to tint a grayscale image. It takes the grayscale image, the tint color, and an option mask image used to ensure the tint only happens in part of the grayscale image. This method also ensure the new image has the same (if any) resizable insets as the original image.
+ (UIImage *)tintImage:(UIImage *)baseImage withColor:(UIColor *)color mask:(UIImage *)maskImage {
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);
if (maskImage) {
CGContextClipToMask(ctx, area, maskImage.CGImage);
} else {
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 (!UIEdgeInsetsEqualToEdgeInsets(baseImage.capInsets, UIEdgeInsetsZero)) {
newImage = [newImage resizableImageWithCapInsets:baseImage.capInsets];
}
return newImage;
}
Here is the non-retina grayscale detail disclosure image:
Here is the retina version:
Here is the non-retina mask (between the quotes - it's mostly white): ""
And the retina mask (between the quotes: ""