如何在iOS和WatchKit中更改图像tintColor

che*_*ewy 373 uiimage uicolor ios swift watchkit

我有一个名为"theImageView"的UIImageView,UIImage为单色(透明背景),就像下面的左黑心一样.如何根据iOS 7+导航栏图标中使用的色调方法在iOS 7或更高版本中以编程方式更改此图像的色调?

这种方法也适用于Apple Watch应用程序的WatchKit吗?

在此输入图像描述

Dun*_*age 713

iOS
对于iOS应用程序,在Swift 3或4中:

theImageView.image = theImageView.image?.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = UIColor.red
Run Code Online (Sandbox Code Playgroud)

斯威夫特2:

theImageView.image = theImageView.image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
theImageView.tintColor = UIColor.redColor()
Run Code Online (Sandbox Code Playgroud)

同时,现代的Objective-C解决方案是:

theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];
Run Code Online (Sandbox Code Playgroud)

Watchkit
在WatchKit for Apple Watch应用程序中,您可以设置模板图像色调颜色.

  1. 您必须将图像添加到WatchKit应用程序中的资产目录,并将图像集设置为在"属性"检查器中呈现为模板图像.与iPhone应用程序不同,您目前无法在WatchKit Extension中的代码中设置模板渲染.
  2. 设置要在应用程序的界面构建器中的WKInterfaceImage中使用的图像
  3. 在WKInterfaceController中为WKInterfaceImage创建一个名为'theImage'的IBOutlet ...

然后在Swift 3或4中设置色调颜色:

theImage.setTintColor(UIColor.red)
Run Code Online (Sandbox Code Playgroud)

斯威夫特2:

theImage.setTintColor(UIColor.redColor())
Run Code Online (Sandbox Code Playgroud)

然后在Objective-C中设置色调颜色:

[self.theImage setTintColor:[UIColor redColor]];
Run Code Online (Sandbox Code Playgroud)

如果您使用模板图像并且不应用色调颜色,则将应用WatchKit应用程序的全局色调.如果您尚未设置全局色调,theImage则在用作模板图像时,默认情况下会浅蓝色.

  • imageWithRenderingMode太慢了.在故事板和图像资产.您也可以更改这两个:将渲染模式更新为模板图像 - 这是一个更好的解决方案 (4认同)
  • 这是最好,最简单的解决方案. (2认同)
  • @Bruno 图像不需要是黑色的,不。适用于任何颜色。 (2认同)

iam*_*sed 121

这是一个应该做的技巧

@interface UIImage(Overlay)
@end

@implementation UIImage(Overlay)

- (UIImage *)imageWithColor:(UIColor *)color1
{
        UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(context, 0, self.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextSetBlendMode(context, kCGBlendModeNormal);
        CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
        CGContextClipToMask(context, rect, self.CGImage);
        [color1 setFill];
        CGContextFillRect(context, rect);
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
}
@end
Run Code Online (Sandbox Code Playgroud)

所以你会这样做:

theImageView.image = [theImageView.image imageWithColor:[UIColor redColor]];
Run Code Online (Sandbox Code Playgroud)


fuz*_*uzz 99

我必须在Swift中使用extension.

我以为我会分享我是如何做到的:

extension UIImage {
    func imageWithColor(color1: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        color1.setFill()

        let context = UIGraphicsGetCurrentContext() as CGContextRef
        CGContextTranslateCTM(context, 0, self.size.height)
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextSetBlendMode(context, CGBlendMode.Normal)

        let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
        CGContextClipToMask(context, rect, self.CGImage)
        CGContextFillRect(context, rect)

        let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage
        UIGraphicsEndImageContext()

        return newImage
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

theImageView.image = theImageView.image.imageWithColor(UIColor.redColor())

斯威夫特4

extension UIImage {
    func imageWithColor(color1: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        color1.setFill()

        let context = UIGraphicsGetCurrentContext()
        context?.translateBy(x: 0, y: self.size.height)
        context?.scaleBy(x: 1.0, y: -1.0)
        context?.setBlendMode(CGBlendMode.normal)

        let rect = CGRect(origin: .zero, size: CGSize(width: self.size.width, height: self.size.height))
        context?.clip(to: rect, mask: self.cgImage!)
        context?.fill(rect)

        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage!
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

theImageView.image = theImageView.image?.imageWithColor(color1: UIColor.red)

  • @CeceXX使用`CGBlendMode.Normal`代替 (7认同)
  • 你太棒了,但是你可能需要把它改成Swift 3 (2认同)

Jer*_*hou 92

在故事板和图像资产.你也可以改变这两个:

将渲染模式更新为模板图像

在图像资源中将渲染模式更新为模板图像

更新视图中的色调颜色.

更新视图中的视图中的色调颜色

  • 这是最糟糕的答案! (21认同)
  • @KamilPowałowski对我来说这有时候有用......我不知道为什么.我希望我知道为什么它并不总是有效.所以我最终通过代码来完成它 (3认同)
  • 对我来说,这个故事板方法适用于按钮,但不适用于imageViews.我仍然需要在imageViews的代码中设置tintColor. (2认同)
  • 如果有人仍在摸索,想知道为什么它不能在IB中工作,请尝试将imageView的Opaque设置为No。 (2认同)

Yan*_*eph 36

斯威夫特4

改变UIImage SVG/PDF的色调,适用于具有独特颜色的图像:

在此输入图像描述 在此输入图像描述

import Foundation

// MARK: - UIImage extensions

public extension UIImage {

    //
    /// Tint Image
    ///
    /// - Parameter fillColor: UIColor
    /// - Returns: Image with tint color
    func tint(with fillColor: UIColor) -> UIImage? {
        let image = withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        fillColor.set()
        image.draw(in: CGRect(origin: .zero, size: size))

        guard let imageColored = UIGraphicsGetImageFromCurrentImageContext() else {
            return nil
        }

        UIGraphicsEndImageContext()
        return imageColored
    }
}
Run Code Online (Sandbox Code Playgroud)

更改UIImageView的色调,适用于具有独特颜色的图像:

在此输入图像描述 在此输入图像描述

let imageView = UIImageView(frame: CGRect(x: 50, y: 50, width: 50, height: 50))
imageView.image = UIImage(named: "hello.png")!.withRenderingMode(.alwaysTemplate)
imageView.tintColor = .yellow
Run Code Online (Sandbox Code Playgroud)

图片更改UIImage的色调,使用:

在此输入图像描述 在此输入图像描述

import Foundation

// MARK: - Extensions UIImage

public extension UIImage {

    /// Tint, Colorize image with given tint color
    /// This is similar to Photoshop's "Color" layer blend mode
    /// This is perfect for non-greyscale source images, and images that 
    /// have both highlights and shadows that should be preserved<br><br>
    /// white will stay white and black will stay black as the lightness of 
    /// the image is preserved
    ///
    /// - Parameter TintColor: Tint color
    /// - Returns:  Tinted image
    public func tintImage(with fillColor: UIColor) -> UIImage {

        return modifiedImage { context, rect in
            // draw black background - workaround to preserve color of partially transparent pixels
            context.setBlendMode(.normal)
            UIColor.black.setFill()
            context.fill(rect)

            // draw original image
            context.setBlendMode(.normal)
            context.draw(cgImage!, in: rect)

            // tint image (loosing alpha) - the luminosity of the original image is preserved
            context.setBlendMode(.color)
            fillColor.setFill()
            context.fill(rect)

            // mask by alpha values of original image
            context.setBlendMode(.destinationIn)
            context.draw(context.makeImage()!, in: rect)
        }
    }

    /// Modified Image Context, apply modification on image
    ///
    /// - Parameter draw: (CGContext, CGRect) -> ())
    /// - Returns:        UIImage
    fileprivate func modifiedImage(_ draw: (CGContext, CGRect) -> ()) -> UIImage {

        // using scale correctly preserves retina images
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        let context: CGContext! = UIGraphicsGetCurrentContext()
        assert(context != nil)

        // correctly rotate image
        context.translateBy(x: 0, y: size.height)
        context.scaleBy(x: 1.0, y: -1.0)

        let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)

        draw(context, rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 嘿,我是 swift 的新手,但你在这里告诉我这是针对 SVG 图像的,但我找不到将 SVG 解析为 UIImage 的方法,你能帮我吗?或者也许我可以用 SVG 正确处理这个问题。谢谢! (2认同)

Put*_*tin 33

如果有人关心解决方案没有UIImageView:

// (Swift 3)
extension UIImage {
    func tint(with color: UIColor) -> UIImage {
        var image = withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        color.set()

        image.draw(in: CGRect(origin: .zero, size: size))
        image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}
Run Code Online (Sandbox Code Playgroud)


Esq*_*uth 17

随着Swift

let commentImageView = UIImageView(frame: CGRectMake(100, 100, 100, 100))
commentImageView.image = UIImage(named: "myimage.png")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
commentImageView.tintColor = UIColor.blackColor()
addSubview(commentImageView)
Run Code Online (Sandbox Code Playgroud)

  • 你可以简单地把`.AlwaysTemplate`. (3认同)

小智 10

这是一个适用于 Swift 5 的简单扩展:

extension UIImageView {

func setImageTintColor(_ color: UIColor) {
    let tintedImage = self.image?.withRenderingMode(.alwaysTemplate)
    self.image = tintedImage
    self.tintColor = color
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

myImageView.setImageTintColor(.systemBlue)
Run Code Online (Sandbox Code Playgroud)


小智 8

快速 3 目的

theImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = UIColor.red
Run Code Online (Sandbox Code Playgroud)


mus*_*afa 7

另外,对于上述答案,在 iOS 13 及更高版本中,有一个干净的方法

let image = UIImage(named: "imageName")?.withTintColor(.white, renderingMode: .alwaysTemplate)
Run Code Online (Sandbox Code Playgroud)


yaz*_*azh 5

尝试这个

http://robots.thoughtbot.com/designing-for-ios-blending-modes

或者

- (void)viewDidLoad
{
[super viewDidLoad];

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 300, 50)];
label.numberOfLines = 0;
label.font = [UIFont systemFontOfSize:13];
label.text = @"These checkmarks use the same gray checkmark image with a tintColor applied to the image view";
[self.view addSubview:label];

[self _createImageViewAtY:100 color:[UIColor purpleColor]];
}

- (void)_createImageViewAtY:(int)y color:(UIColor *)color {
UIImage *image = [[UIImage imageNamed:@"gray checkmark.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect frame = imageView.frame;
frame.origin.x = 100;
frame.origin.y = y;
imageView.frame = frame;

if (color)
    imageView.tintColor = color;

[self.view addSubview:imageView];
}
Run Code Online (Sandbox Code Playgroud)


F.s*_*.sh 5

用于为 UIButton 的图像着色

let image1 = "ic_shopping_cart_empty"
btn_Basket.setImage(UIImage(named: image1)?.withRenderingMode(.alwaysTemplate), for: .normal)
btn_Basket.setImage(UIImage(named: image1)?.withRenderingMode(.alwaysTemplate), for: .selected)
btn_Basket.imageView?.tintColor = UIColor(UIColor.Red)
Run Code Online (Sandbox Code Playgroud)