ChatGPT解决这个技术问题 Extra ChatGPT

颜色色调 UIButton 图像

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

您可以发布您想要使用的图像以及所需结果的图像吗?
这在界面生成器 stackoverflow.com/a/25179217/2051381 中执行相同的操作

R
Ric Santos

从 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

我认为最好使用 button.imageView.tintColor
@M.Othman 仅在我使用 button.tintColor 而不是 button.imageview.tintColor 时对我有用
只要记住在每个@hashier 的xcassets 中设置图像渲染模式
创建 UIButtonTypeSystem 类型的 UIButton 将自动遵循您设置的 tintColor。
如果您的 tintColor 太暗,请确保 adjustsImageWhenHighlighted 为 NO。 (或在 IB 中:“突出显示调整图像”未选中。)
C
Community

正如 Ric 在他的 post 中已经提到的,您可以在代码中设置渲染模式,您也可以直接在图像目录中执行此操作,请参见下面的附图。只需将 Render As 设置为 Template Image

https://i.stack.imgur.com/5V3qQ.png

警告 我在使用 iOS 7 和这种方法时遇到了问题。因此,如果您也使用 iOS 7,您可能也希望在代码中执行此操作,以确保,如 here 所述。


作为旁注,图像文件应该是黑色和透明的(不是黑白)
@AxelGuilmin 不是真的。您的图像可以是您想要的任何颜色并且是透明的。任何不同于透明的颜色都将转换为通用颜色,然后默认为黑色。
a
auco

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

https://i.stack.imgur.com/1tS8o.png

(在 iOS9、Xcode 7.3 上测试)


使用此处建议的 alwaysTemplate 和 tintColor 方法可以避免这种情况。凭借 .system 按钮的优势,您可以通过点击轻触来改变颜色。
M
Marcin Kaczmarzyk

您必须将图像呈现模式设置为 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

I
Ilker Baltaci

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

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

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

https://i.stack.imgur.com/e9cW7.png

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


如果您在这里,您可以转到此链接:useyourloaf.com/blog/styling-buttons-using-the-asset-catalog 并转到模板图像(作为解释)
这是一个更好的解决方案,因为它减少了代码并且与公认的答案几乎相同。
我认为这应该是正确的。代码更少,易于处理。
h
henrik-dmg

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


K
Kirby Todd

不确定你到底想要什么,但这个类别方法会用指定的颜色屏蔽 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];

CGBitmapContextCreate 上使用 kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast
不错,但需要针对 Retina 图形进行调整...当我在 Retina 图像上运行它时,它返回给我一个非视网膜图像。
要支持 Retina 设备,您可以使用 UIDevice 类的 scale 属性: CGFloat scale = [UIScreen mainScreen].scale; CGFloat width = self.size.width * scale; CGFloat height = self.size.height * scale; scale 属性从 iOS 4.0 开始存在。
您还需要在创建 UIImage 时使用 scale 值:UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:scale orientation:self.imageOrientation];
a
aBikis

带有 customType 的 Swift 4:

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

A
Alessandro Ornano

斯威夫特 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 扩展名,颜色的变化是即时的..


Ş
Şafak Gezer

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

J
Josh Bernfeld

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

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

F
Faruk
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 之间。


g
guptha

你应该试试

设置框架后

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

}

J
Jad

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

M
Makalele

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

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

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

S
Szymon Klimaszewski

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

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

D
Dhananjay M

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

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

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

https://i.stack.imgur.com/Tf92G.png


D
Daniel Sadka

我在突出显示状态下屏蔽图像时遇到问题。我不希望它发生。如果你有同样的问题,看看这个:adjustsImageWhenHighlighted = false