颜色着色UIButton图像

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

221996 次浏览

你应该试试

设置好框架后

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];


}

不确定你到底想要什么,但这个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];

从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

正如Ric已经在他的帖子中提到的,你可以在代码中设置渲染模式,你也可以直接在图像目录中这样做,见下面所附的图像。只需要将Render As设置为Template Image

enter image description here

警告我有问题与iOS 7和这种方法。所以如果你也使用iOS 7,你可能也想在代码中做到这一点,如所述在这里

为了让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

在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

8 .编辑Xcode 现在你也可以只在你的.xcassets模板图像图像的图像呈现模式,然后你不需要特别声明它在var exampleImage

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

- (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;
}

自定义按钮以它们各自的图像颜色出现。在故事板中将按钮类型设置为“System”(或在代码中设置为UIButtonTypeSystem),将以默认的色调呈现按钮的图像。

Button Type System rendericons tinted .

(在iOS9, Xcode 7.3上测试)

斯威夫特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)

Swift 4与customType:

let button = UIButton(frame: aRectHere)
let buttonImage = UIImage(named: "imageName")
button.setImage(buttonImage?.withRenderingMode(.alwaysTemplate), for: .normal)
button.tintColor = .white

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);

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

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

在图像的属性检查器中设置渲染值为“Template image”

enter image description here

现在,当你设置__abc0时,你的按钮将显示为红色。

改变按钮图像或图像视图色调颜色

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


btn.imageView?.tintColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)

斯威夫特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)

附注:(在表格单元格中工作也很好,你不需要调用setNeedDisplay()方法,由于用户界面图像扩展,颜色的变化是立即的。

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

button.setImageTintColor(Palette.darkGray(), for: UIControlState())

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

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

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

截图:enter image description here

let button = UIButton(type: .custom)
let image = UIImage(named: "image_name")?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.red

如果你用UIColor(r:g:b:alpha:)来设置UIButton.tintColor,记住值要除以255。这些RGB值应该在0和1之间。

我有一个问题,掩蔽图像在突出显示的状态。我不希望发生这种事。如果你有同样的问题,看看这个:adjustsImageWhenHighlighted = false

如果你是在iOS 15之后到达这里,并且你正在使用新的UIButton.Configuration api,那么你可能需要通过imageColorTransformer

看起来是这样的:

configuration.imageColorTransformer = UIConfigurationColorTransformer { _ in .green }

为了方便,你可以创建一个扩展:

extension UIButton.Configuration {
func imageColor(_ color: UIColor) -> UIButton.Configuration {
var configuration = self
configuration.imageColorTransformer = UIConfigurationColorTransformer { _ in color }
return configuration
}
}


// Usage:
configuration = configuration.imageColor(.cyan)

与其他答案一样,图像本身必须“渲染为模板图像”。在Xcode资产或代码image.withRenderingMode(.alwaysTemplate)