330

我注意到,当我将白色或黑色UIImage放入 aUISegmentedControl时,它会自动对其进行颜色遮罩以匹配分段控件的色调。我认为这真的很酷,并且想知道我是否也可以在其他地方这样做。例如,我有一堆形状统一但颜色多样的按钮。除了为每个按钮制作一个 PNG 之外,我是否可以以某种方式使用这种颜色遮罩为所有按钮使用相同的图像,然后设置一个色调颜色或其他东西来改变它们的实际颜色?

4

17 回答 17

685

从 iOS 7 开始,有一个新的方法UIImage来指定渲染模式。使用渲染模式UIImageRenderingModeAlwaysTemplate将允许图像颜色由按钮的色调颜色控制。

Objective-C

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *image = [[UIImage imageNamed:@"image_name"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[button setImage:image forState:UIControlStateNormal]; 
button.tintColor = [UIColor redColor];

迅速

let button = UIButton(type: .custom)
let image = UIImage(named: "image_name")?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.red
于 2014-07-27T09:21:34.703 回答
241

As Ric already mentioned in his post you can set the render mode in code, you can also do this directly in the image catalog, see attached image below. Just set the Render As to Template Image

enter image description here

Caveat I have had problems with iOS 7 and this approach. So if you use iOS 7 as well you might want to do it in code as well to be sure, as described here.

于 2014-11-25T09:10:50.203 回答
102

自定义按钮以其各自的图像颜色显示。在情节提要中(或在代码中)将按钮类型设置为“系统” UIButtonTypeSystem,将使用默认色调呈现按钮的图像。

按钮类型系统呈现有色图标

(在 iOS9、Xcode 7.3 上测试)

于 2016-06-25T16:49:35.660 回答
49

您必须将图像渲染模式设置为UIImageRenderingModeAlwaysTemplate才能tintColor影响 UIImage。这是 Swift 中的解决方案:

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

斯威夫特 4x

button.setImage(image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate), for: .normal)
button.tintColor = UIColor.blue
于 2014-12-05T07:50:02.493 回答
36

如果您有一个带有背景图像的自定义按钮。您可以设置按钮的色调颜色并使用以下内容覆盖图像。

在资产中选择要设置色调颜色的按钮背景。

在图像的属性检查器中,将值渲染设置为“模板图像”

在此处输入图像描述

现在,每当您设置按钮时button.tintColor = UIColor.red,按钮都会显示为红色。

于 2017-04-13T13:26:16.230 回答
18

在 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 中的图像渲染模式转换为模板图像,然后您就不需要再专门声明它var exampleImage

于 2015-05-10T12:23:17.213 回答
14

不确定你到底想要什么,但这个类别方法会用指定的颜色屏蔽 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];
于 2013-11-07T06:42:04.470 回答
8

带有 customType 的 Swift 4:

let button = UIButton(frame: aRectHere)
    let buttonImage = UIImage(named: "imageName")
    button.setImage(buttonImage?.withRenderingMode(.alwaysTemplate), for: .normal)
    button.tintColor = .white
于 2016-10-11T20:28:25.090 回答
6

斯威夫特 3

如果您已经通过 xCode 界面构建器设置了图像,则此解决方案可能会很舒服。基本上你有一个扩展来为图像着色:

extension UIImage {
    public func image(withTintColor color: UIColor) -> UIImage{
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        context.translateBy(x: 0, y: self.size.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.setBlendMode(CGBlendMode.normal)
        let rect: CGRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
        context.clip(to: rect, mask: self.cgImage!)
        color.setFill()
        context.fill(rect)
        let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImage
    }
}

然后,您可以准备这个UIButton扩展来为特定状态的图像着色:

extension UIButton {
    func imageWith(color:UIColor, for: UIControlState) {
        if let imageForState = self.image(for: state) {
            self.image(for: .normal)?.withRenderingMode(.alwaysTemplate)
            let colorizedImage = imageForState.image(withTintColor: color)
            self.setImage(colorizedImage, for: state)
        }
    }
}

用法:

myButton.imageWith(.red, for: .normal)

PS(在表格单元格中也可以正常工作,您不需要调用方法,由于UIImagesetNeedDisplay()扩展,颜色的变化是立即的。.

于 2017-07-15T10:34:54.410 回答
5

对于 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);
于 2016-10-25T07:39:42.037 回答
3

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

- (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;
}
于 2015-08-10T05:40:55.750 回答
2

你应该试试

设置框架后

NSArray *arr10 =[NSArray arrayWithObjects:btn1,btn2,nil];
for(UIButton *btn10 in arr10)
{
CAGradientLayer *btnGradient2 = [CAGradientLayer layer];
btnGradient2.frame = btn10.bounds;

btnGradient2.colors = [NSArray arrayWithObjects:
                       (id)[[UIColor colorWithRed:151.0/255.0f green:206.0/255.5 blue:99.0/255.0 alpha:1] CGColor],
                       (id)[[UIColor colorWithRed:126.0/255.0f green:192.0/255.5 blue:65.0/255.0 alpha:1]CGColor],
                       nil];
[btn10.layer insertSublayer:btnGradient2 atIndex:0];

}
于 2013-11-07T06:33:19.933 回答
2

斯威夫特 3.0

    let image = UIImage(named:"NoConnection")!

 warningButton = UIButton(type: .system)        
    warningButton.setImage(image, for: .normal)
    warningButton.tintColor = UIColor.lightText
    warningButton.frame = CGRect(origin: CGPoint(x:-100,y:0), size: CGSize(width: 59, height: 56))

    self.addSubview(warningButton)
于 2016-09-30T19:48:19.110 回答
1

更改按钮图像或图像视图色调颜色 Swift :

btn.imageView?.image = btn.imageView?.image?.withRenderingMode(.alwaysTemplate)

btn.imageView?.tintColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
于 2017-07-13T13:55:32.973 回答
1
let button = UIButton(type: .custom)
let image = UIImage(named: "image_name")?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.red

如果您设置UIButton.tintColorUIColor(r:g:b:alpha:),请记住将值除以255。这些 RGB 值应介于 0 和 1 之间。

于 2021-04-08T13:23:39.093 回答
0

以上都不适合我,因为点击后色调被清除。我不得不使用

button.setImageTintColor(Palette.darkGray(), for: UIControlState())
于 2018-09-26T20:23:46.077 回答
0

要在按钮上设置图像(箭头图标)的白色,我们使用:

let imageOnButton = UIImage(named: "navForwardArrow")?.imageWithColor(color: UIColor.white)
button.setImage(imageOnButton, for: .normal)

已知问题:按下按钮时图标失去白色。

截屏:在此处输入图像描述

于 2021-02-22T13:12:40.503 回答