我注意到当我将一个白色或黑色的 UIImage 放入 UISegmentedControl 时,它会自动对其进行颜色遮罩以匹配分段控件的色调 . 我觉得这真的很酷,想知道我是否也可以在其他地方做到这一点 . 例如,我有一堆按钮,它们具有统一的形状但颜色各异 . 我不是为每个按钮制作一个PNG,而是以某种方式使用这种颜色遮罩来为所有这些使用相同的图像,但是然后设置一种色彩或某种东西来改变它们的实际颜色?
UIImage
UISegmentedControl
从iOS 7开始, UIImage 上有一个新方法来指定渲染模式 . 使用渲染模式 UIImageRenderingModeAlwaysTemplate 将允许图像颜色由按钮的色调控制 .
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在他的post中已经提到的,您可以在代码中设置渲染模式,您也可以直接在图像目录中执行此操作,请参见下面的附图 . 只需将 Render As 设置为 Template Image
Render As
Template Image
Caveat 我遇到过iOS 7和这种方法的问题 . 因此,如果您使用iOS 7,您也可以在代码中进行操作以确保,如here所述 .
Custom Buttons 以各自的图像颜色显示 . 在故事板中将按钮类型设置为"System"(或在代码中设置为 UIButtonTypeSystem ),将使用默认的色调颜色呈现按钮的图像 .
(在iOS9上测试,Xcode 7.3)
必须将图像渲染模式设置为 UIImageRenderingModeAlwaysTemplate 才能使 tintColor 影响UIImage . 这是Swift中的解决方案:
tintColor
let image = UIImage(named: "image-name") let button = UIButton() button.setImage(image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), forState: .Normal) button.tintColor = UIColor.whiteColor()
如果您有一个带背景图像的自定义按钮 . 您可以设置按钮的色调颜色并覆盖图像 .
在资源中,选择要设置色调颜色的按钮背景 .
在图像集的属性检查器中,值呈现为“模板图像”
现在,无论何时设置 button.tintColor = UIColor.red ,您的按钮都将显示为红色 .
button.tintColor = UIColor.red
在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
EDIT Xcode 8 现在你也可以只将.xcassets中图像的渲染模式转换为模板图像,然后你就不需要在_1764485中再具体声明它了 .
不确定你想要什么,但这个类别方法将掩盖具有指定颜色的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];
带有customType的Swift 4:
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);
Swift 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) } } }
Usage:
myButton.imageWith(.red, for: .normal)
附: (在表格单元格中工作也很好,你不需要调用 setNeedDisplay() 方法,由于 UIImage 扩展名,颜色的变化是立竿见影的 .
setNeedDisplay()
如果您想手动屏蔽图像,这里是更新的代码,适用于视网膜屏幕
- (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; }
你应该试试
设置框架后
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]; }
Swift 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:
btn.imageView?.image = btn.imageView?.image?.withRenderingMode(.alwaysTemplate)
btn.imageView?.tintColor = #colorLiteral(红色:0,绿色:0,蓝色:0,alpha:1)
以上都不适合我,因为点击后清除了色调 . 我不得不使用
button.setImageTintColor(Palette.darkGray(), for: UIControlState())
15 回答
从iOS 7开始,
UIImage
上有一个新方法来指定渲染模式 . 使用渲染模式UIImageRenderingModeAlwaysTemplate
将允许图像颜色由按钮的色调控制 .Objective-C的
迅速
正如Ric在他的post中已经提到的,您可以在代码中设置渲染模式,您也可以直接在图像目录中执行此操作,请参见下面的附图 . 只需将
Render As
设置为Template Image
Caveat 我遇到过iOS 7和这种方法的问题 . 因此,如果您使用iOS 7,您也可以在代码中进行操作以确保,如here所述 .
Custom Buttons 以各自的图像颜色显示 . 在故事板中将按钮类型设置为"System"(或在代码中设置为 UIButtonTypeSystem ),将使用默认的色调颜色呈现按钮的图像 .
(在iOS9上测试,Xcode 7.3)
必须将图像渲染模式设置为
UIImageRenderingModeAlwaysTemplate
才能使tintColor
影响UIImage . 这是Swift中的解决方案:如果您有一个带背景图像的自定义按钮 . 您可以设置按钮的色调颜色并覆盖图像 .
在资源中,选择要设置色调颜色的按钮背景 .
在图像集的属性检查器中,值呈现为“模板图像”
现在,无论何时设置
button.tintColor = UIColor.red
,您的按钮都将显示为红色 .在Swift中你可以这样做:
然后在你的viewDidLoad中
并修改颜色
EDIT Xcode 8 现在你也可以只将.xcassets中图像的渲染模式转换为模板图像,然后你就不需要在_1764485中再具体声明它了 .
不确定你想要什么,但这个类别方法将掩盖具有指定颜色的UIImage,因此您可以拥有单个图像并将其颜色更改为您想要的任何颜色 .
ImageUtils.h
ImageUtils.m
导入ImageUtils类别并执行以下操作...
带有customType的Swift 4:
对于Xamarin.iOS(C#):
Swift 3 :
如果您已通过xCode界面构建器设置了图像,则此解决方案可能会很舒适 . 基本上你有一个扩展来着色图像:
然后,您可以准备此 UIButton 扩展名以为特定状态的图像着色:
Usage:
附: (在表格单元格中工作也很好,你不需要调用
setNeedDisplay()
方法,由于 UIImage 扩展名,颜色的变化是立竿见影的 .如果您想手动屏蔽图像,这里是更新的代码,适用于视网膜屏幕
你应该试试
设置框架后
Swift 3.0
更改按钮图像或图像视图色调颜色Swift:
btn.imageView?.image = btn.imageView?.image?.withRenderingMode(.alwaysTemplate)
btn.imageView?.tintColor = #colorLiteral(红色:0,绿色:0,蓝色:0,alpha:1)
以上都不适合我,因为点击后清除了色调 . 我不得不使用