I noticed that when I place a white or black UIImage into a UISegmentedControl it automatically color masks it to match the tint of the segmented control. I thought this was really cool, and was wondering if I could do this elsewhere as well. For example, I have a bunch of buttons that have a uniform shape but varied colors. Instead of making a PNG for each button, could I somehow use this color masking to use the same image for all of them but then set a tint color or something to change their actual color?


当前回答

在Swift中,你可以这样做:

var exampleImage = UIImage(named: "ExampleImage.png")?.imageWithRenderingMode(.AlwaysTemplate)

然后在viewDidLoad中

exampleButtonOutlet.setImage(exampleImage, forState: UIControlState.Normal)

并修改颜色

exampleButtonOutlet.tintColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1) //your color

编辑Xcode 8 现在你也可以在你的.xcassets to Template image中设置图像的呈现模式,然后你就不需要在var exampleImage中特别声明它了

其他回答

为了让tintColor影响UIImage,你必须将图像渲染模式设置为UIImageRenderingModeAlwaysTemplate。以下是Swift中的解决方案:

let image = UIImage(named: "image-name")
let button = UIButton()
button.setImage(image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), forState: .Normal)
button.tintColor = UIColor.whiteColor()

快4倍

button.setImage(image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate), for: .normal)
button.tintColor = UIColor.blue

如果你想手动屏蔽你的图像,这里是更新的代码,适用于视网膜屏幕

- (UIImage *)maskWithColor:(UIColor *)color
{
    CGImageRef maskImage = self.CGImage;
    CGFloat width = self.size.width * self.scale;
    CGFloat height = self.size.height * self.scale;
    CGRect bounds = CGRectMake(0,0,width,height);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, width, height, 8, 0, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);
    CGContextClipToMask(bitmapContext, bounds, maskImage);
    CGContextSetFillColorWithColor(bitmapContext, color.CGColor);
    CGContextFillRect(bitmapContext, bounds);

    CGImageRef cImage = CGBitmapContextCreateImage(bitmapContext);
    UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:self.scale orientation:self.imageOrientation];

    CGContextRelease(bitmapContext);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cImage);

    return coloredImage;
}

在Swift中,你可以这样做:

var exampleImage = UIImage(named: "ExampleImage.png")?.imageWithRenderingMode(.AlwaysTemplate)

然后在viewDidLoad中

exampleButtonOutlet.setImage(exampleImage, forState: UIControlState.Normal)

并修改颜色

exampleButtonOutlet.tintColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1) //your color

编辑Xcode 8 现在你也可以在你的.xcassets to Template image中设置图像的呈现模式,然后你就不需要在var exampleImage中特别声明它了

Xamarin的。iOS (c#):

UIButton messagesButton = new UIButton(UIButtonType.Custom);
UIImage icon = UIImage.FromBundle("Images/icon.png");
messagesButton.SetImage(icon.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), UIControlState.Normal);
messagesButton.TintColor = UIColor.White;
messagesButton.Frame = new RectangleF(0, 0, 25, 25);

不确定你到底想要什么,但这个category方法会用指定的颜色掩盖一个UIImage,所以你可以有一个单独的图像,改变它的颜色为任何你想要的。

ImageUtils.h

- (UIImage *) maskWithColor:(UIColor *)color;

ImageUtils.m

-(UIImage *) maskWithColor:(UIColor *)color 
{
    CGImageRef maskImage = self.CGImage;
    CGFloat width = self.size.width;
    CGFloat height = self.size.height;
    CGRect bounds = CGRectMake(0,0,width,height);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, width, height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
    CGContextClipToMask(bitmapContext, bounds, maskImage);
    CGContextSetFillColorWithColor(bitmapContext, color.CGColor);    
    CGContextFillRect(bitmapContext, bounds);

    CGImageRef cImage = CGBitmapContextCreateImage(bitmapContext);
    UIImage *coloredImage = [UIImage imageWithCGImage:cImage];

    CGContextRelease(bitmapContext);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cImage);

    return coloredImage;    
}

导入ImageUtils类别并执行如下操作…

#import "ImageUtils.h"

...

UIImage *icon = [UIImage imageNamed:ICON_IMAGE];

UIImage *redIcon = [icon maskWithColor:UIColor.redColor];
UIImage *blueIcon = [icon maskWithColor:UIColor.blueColor];