颜色色调UIButton图像


294

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


您可以发布想要使用的图像,也可以发布所需效果的图像吗?
Pratyusha Terli

Answers:


619

从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

14
我认为最好使用button.imageView.tintColor
M.Othman

3
@ M.Othman仅对我有用,当我使用button.tintColor而不是button.imageview.tintColor时
pnizzle

32
只要记住要在每个@hashier的xcassets中为图像设置图像渲染模式
Dean

23
创建UIButtonTypeSystem类型的UIButton将自动接受您设置的tintColor。
carloshwa 2015年

4
如果您tintColor太黑,请确保adjustsImageWhenHighlighted否。(或者在IB中:未选中“突出显示的图像”。)
Jason Moore

225

正如Ric在他的帖子中已经提到的那样,您可以在代码中设置渲染模式,也可以直接在图像目录中进行设置,请参见下面的图像。只需将设置Render AsTemplate Image

在此处输入图片说明

请注意,我在使用iOS 7和这种方法时遇到了问题。所以,如果你使用的iOS 7,以及你可能想要做的代码,以及可以肯定,作为描述在这里


1
附带说明,图像文件应为黑色且透明(不是黑白)
Axel Guilmin

6
@AxelGuilmin并非如此。您的图像可以是您想要的任何颜色,也可以是透明的。与透明不同的任何颜色都将转换为通用颜色,然后默认情况下将其着色为黑色。
亚历杭德罗·伊万

90

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

按钮类型系统渲染有色图标

(在iOS9,Xcode 7.3上测试)


2
使用此处建议的alwaysTemplate和tintColor方法可以避免这种情况。利用.system按钮的优势,您只需轻按一下水龙头即可更改颜色。
克里斯·普林斯

44

您必须将图像渲染模式设置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

28

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

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

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

在此处输入图片说明

现在,无论何时设置button.tintColor = UIColor.red,按钮都会显示为红色。


如果您在这里,则可以转到此链接:useyourloaf.com/blog/styling-buttons-using-the-asset-catalog并转到模板图像(作为解释)
cspam

这是一个更好的解决方案,因为它减少了代码,并且几乎与接受的答案具有相同的作用。
DS。

我认为这应该是正确的。更少的代码,易于处理。
Umair_UAS

17

在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了。


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

3
kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLastCGBitmapContextCreate
Luis Ascorbe 2014年

4
很好,但是需要针对Retina图形进行调整...当我在Retina图像上运行此图像时,它返回的是非视网膜图像。
jowie 2014年

要支持Retina设备,可以使用UIDevice该类的scale属性:CGFloat scale = [UIScreen mainScreen].scale; CGFloat width = self.size.width * scale; CGFloat height = self.size.height * scale;scale属性从iOS 4.0开始存在。
菲利普·弗里施穆特

创建scale时,您还需要使用该值UIImageUIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:scale orientation:self.imageOrientation];
Philipp Frischmuth 2015年

8

带有customType的Swift 4:

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

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

5

迅捷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扩展,颜色的更改是立即的。


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

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

}

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)

1

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.