我注意到,当我将白色或黑色UIImage
放入其中时,UISegmentedControl
它会自动对其进行颜色遮罩,以匹配分段控件的色彩。我认为这真的很酷,并且想知道我是否也可以在其他地方这样做。例如,我有一堆形状统一但颜色不同的按钮。除了可以为每个按钮制作一个PNG之外,我还可以某种方式使用此颜色遮罩对所有按钮使用相同的图像,然后设置淡色或更改其实际颜色的方法吗?
我注意到,当我将白色或黑色UIImage
放入其中时,UISegmentedControl
它会自动对其进行颜色遮罩,以匹配分段控件的色彩。我认为这真的很酷,并且想知道我是否也可以在其他地方这样做。例如,我有一堆形状统一但颜色不同的按钮。除了可以为每个按钮制作一个PNG之外,我还可以某种方式使用此颜色遮罩对所有按钮使用相同的图像,然后设置淡色或更改其实际颜色的方法吗?
Answers:
从iOS 7开始,有一种新方法UIImage
可以指定渲染模式。使用渲染模式UIImageRenderingModeAlwaysTemplate
将允许图像颜色由按钮的色彩控制。
物镜
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
tintColor
太黑,请确保adjustsImageWhenHighlighted
否。(或者在IB中:未选中“突出显示的图像”。)
您必须将图像渲染模式设置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()
SWIFT 4倍
button.setImage(image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate), for: .normal)
button.tintColor = UIColor.blue
如果您有带有背景图像的自定义按钮。您可以设置按钮的色调颜色,并使用以下命令覆盖图像。
在资产中,选择要设置颜色的按钮背景。
在图像的属性检查器中,将值render设置为“模板图像”
现在,无论何时设置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
编辑Xcode 8
现在,您也可以只将.xcassets中的图像渲染模式转换为Template Image,然后就不再需要专门声明它var exampleImage
了。
不确定是否确切想要什么,但是此类别方法将用指定的颜色遮罩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];
kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast
在CGBitmapContextCreate
UIDevice
该类的scale属性:CGFloat scale = [UIScreen mainScreen].scale; CGFloat width = self.size.width * scale; CGFloat height = self.size.height * scale;
该scale
属性从iOS 4.0开始存在。
scale
时,您还需要使用该值UIImage
:UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:scale orientation:self.imageOrientation];
对于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);
迅捷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(在表格单元格中也很好用,您不需要调用setNeedDisplay()
方法,由于UIImage扩展,颜色的更改是立即的。
如果您要手动遮盖图像,请使用以下更新的代码,该代码适用于视网膜屏幕
- (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];
}
斯威夫特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)
以上都不适合我,因为单击后清除了色调。我不得不用
button.setImageTintColor(Palette.darkGray(), for: UIControlState())