如何更改iOS和WatchKit中的图像颜色

如何更改iOS和WatchKit中的图像颜色,ios,swift,uiimage,uicolor,watchkit,Ios,Swift,Uiimage,Uicolor,Watchkit,我有一个名为“theImageView”的UIImageView,UIImageView采用单一颜色(透明背景),就像下面的左黑心一样。如何根据iOS 7+导航栏图标中使用的着色方法,在iOS 7或更高版本中以编程方式更改此图像的着色颜色 这种方法是否也适用于Apple Watch应用程序的WatchKit 这里有一个类别应该可以做到这一点 @interface UIImage(Overlay) @end @implementation UIImage(Overlay) - (UIImage

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

这种方法是否也适用于Apple Watch应用程序的WatchKit


这里有一个类别应该可以做到这一点

@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
所以你会这样做:

theImageView.image = [theImageView.image imageWithColor:[UIColor redColor]];

我必须在Swift中使用
扩展名

我想分享一下我是如何做到的:

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
    }
}
用法:

myImageView.setImageTintColor(.systemBlue)
theImageView.image=theImageView.image.imageWithColor(UIColor.redColor())

Swift 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!
    }
}
用法:

myImageView.setImageTintColor(.systemBlue)
theImageView.image=theImageView.image?.imageWithColor(color1:UIColor.red)
试试这个

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

theImageView.image = theImageView.image?.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = UIColor.red
对于Swift 2:

theImageView.image = theImageView.image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
theImageView.tintColor = UIColor.redColor()
同时,现代Objective-C解决方案是:

theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];

手表套件
在Apple Watch应用程序的WatchKit中,您可以设置

  • 您必须将图像添加到WatchKit应用程序中的资产目录,并将图像集设置为在属性检查器中呈现为模板图像。与iPhone应用程序不同,目前无法在WatchKit扩展中的代码中设置模板呈现
  • 在应用程序的interface builder中设置要在WKInterfaceImage中使用的图像
  • 在WKInterfaceController中为WKInterfaceImage创建一个名为“theImage”的IBOutlet
  • 然后在Swift 3或4中设置色调颜色:

    theImage.setTintColor(UIColor.red)
    
    Swift 2:

    theImage.setTintColor(UIColor.redColor())
    
    然后在Objective-C中设置色调颜色:

    [self.theImage setTintColor:[UIColor redColor]];
    
    如果您使用模板图像且未应用着色,则将应用WatchKit应用程序的全局着色。如果您尚未设置全局色调,
    图像用作模板图像时,默认情况下将为浅蓝色。

    使用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)
    

    在情节提要和图像资源中。您还可以更改这两个选项:

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

    更新视图中的着色颜色

    Swift 4 更改UIImage SVG/PDF的色调,该色调适用于具有唯一颜色的图像:

    更改适用于具有唯一颜色的图像的UIImageView的色调:

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

    <代码>导入基础 //标记:-图像的扩展 公共图像扩展{ ///着色,使用给定的着色颜色为图像着色 ///这类似于Photoshop的“颜色”图层混合模式 ///这对于非灰度源图像和 ///同时具有应保留的高光和阴影

    ///白色将保持白色,黑色将保持黑色,因为 ///图像被保留 /// ///-参数TintColor:色调颜色 ///-返回:着色图像 公共func tintImage(带fillColor:UIColor)->UIImage{ 返回modifiedImage{context,rect in //绘制黑色背景-保留部分透明像素颜色的解决方法 context.setBlendMode(.normal) UIColor.black.setFill() context.fill(rect) //绘制原始图像 context.setBlendMode(.normal) context.draw(cgImage!,in:rect) //着色图像(丢失alpha)-保留原始图像的亮度 context.setBlendMode(.color) fillColor.setFill() context.fill(rect) //通过原始图像的alpha值进行遮罩 context.setBlendMode(.destinationIn) context.draw(context.makeImage()!,in:rect) } } ///修改图像上下文,对图像应用修改 /// ///-参数绘制:(CGContext,CGRect)->()) ///-返回:UIImage fileprivate func modifiedImage(uDraw:(CGContext,CGRect)->())->UIImage{ //使用scale可以正确地保存视网膜图像 UIGraphicsBeginImageContextWithOptions(大小、错误、比例) let context:CGContext!=UIGraphicsGetCurrentContext() 断言(上下文!=nil) //正确旋转图像 context.translateBy(x:0,y:size.height) context.scaleBy(x:1.0,y:-1.0) 设rect=CGRect(x:0.0,y:0.0,宽度:size.width,高度:size.height) 绘制(上下文,矩形) 让image=UIGraphicsGetImageFromCurrentImageContext() UIGraphicsSendImageContext() 返回图像! } }
    现在我在Duncan Babbage响应中使用了这种方法:

    + (UIImageView *) tintImageView: (UIImageView *)imageView withColor: (UIColor*) color{
        imageView.image = [imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
        [imageView setTintColor:color];
        return imageView;
    }
    
    用于swift 3目的

    theImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate)
    theImageView.tintColor = UIColor.red
    
    如果有图像替换清除按钮,可以在Swift 3中使用此按钮


    利用Swift中的扩展:-

    extension UIImageView {
        func changeImageColor( color:UIColor) -> UIImage
        {
            image = image!.withRenderingMode(.alwaysTemplate)
            tintColor = color
            return image!
        }
    }
    
       //Change color of logo 
       logoImage.image =  logoImage.changeImageColor(color: .red)
    

    如果有人关心没有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
        }
    }
    

    也可从代码和界面生成器使用的子类:

    @implementation TintedImageView
    
    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            [self setup];
        }
        return self;
    }
    
    - (instancetype)initWithCoder:(NSCoder *)aDecoder {
        self = [super initWithCoder:aDecoder];
        if (self) {
            [self setup];
        }
        return self;
    }
    
    -(void)setup {
        self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    }
    
    @end
    
    iOS

    从Interface Builder执行此操作的解决方案,并从IB中选择您的着色颜色

    extension UIImageView {
    
    // make template image with tint color
    var templateImage: Bool {
        set {
            if newValue, let image = self.image {
                let newImage = image.withRenderingMode(.alwaysTemplate)
                self.image = newImage
            }
        } get {
            return false
        }
    }
    

    }

    这是我的UIImage扩展,您可以直接对图像使用changeTintColor功能

    extension UIImage {
    
        func changeTintColor(color: UIColor) -> UIImage {
            var newImage = self.withRenderingMode(.alwaysTemplate)
            UIGraphicsBeginImageContextWithOptions(self.size, false, newImage.scale)
            color.set()
            newImage.draw(in: CGRect(x: 0.0, y: 0.0, width: self.size.width, height: self.size.height))
            newImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return newImage
        }
    
        func changeColor(color: UIColor) -> UIImage {
            let backgroundSize = self.size
            UIGraphicsBeginImageContext(backgroundSize)
            guard let context = UIGraphicsGetCurrentContext() else {
                return self
            }
            var backgroundRect = CGRect()
            backgroundRect.size = backgroundSize
            backgroundRect.origin.x = 0
            backgroundRect.origin.y = 0
    
            var red: CGFloat = 0
            var green: CGFloat = 0
            var blue: CGFloat = 0
            var alpha: CGFloat = 0
            color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
            context.setFillColor(red: red, green: green, blue: blue, alpha: alpha)
            context.translateBy(x: 0, y: backgroundSize.height)
            context.scaleBy(x: 1.0, y: -1.0)
            context.clip(to: CGRect(x: 0.0, y: 0.0, width: self.size.width, height: self.size.height),
                     mask: self.cgImage!)
            context.fill(backgroundRect)
    
            var imageRect = CGRect()
            imageRect.size = self.size
            imageRect.origin.x = (backgroundSize.width - self.size.width) / 2
            imageRect.origin.y = (backgroundSize.height - self.size.height) / 2
    
            context.setBlendMode(.multiply)
            context.draw(self.cgImage!, in: imageRect)
    
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return newImage!
        }
    
    }
    
    类似这样的示例用法

    let image = UIImage(named: "sample_image")
    imageView.image = image.changeTintColor(color: UIColor.red)
    

    您可以使用change
    changeColor
    功能更改图像颜色

    Swift 3版本的扩展答案,从fuzz


    profileImageView.image=图像视图.image!。使用渲染模式(.alwaysTemplate)
    profileImageView.tintColor=UIColor.green

    首先在“图像资源”中选择特定图像,然后选择“变红为模板”而不是“默认”,然后选择“写入行”。
    profileImageView.tintColor=UIColor.green

    用于为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)
    

    如果您有SVG图像的任何id
    extension UIImage {
    
        func changeTintColor(color: UIColor) -> UIImage {
            var newImage = self.withRenderingMode(.alwaysTemplate)
            UIGraphicsBeginImageContextWithOptions(self.size, false, newImage.scale)
            color.set()
            newImage.draw(in: CGRect(x: 0.0, y: 0.0, width: self.size.width, height: self.size.height))
            newImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return newImage
        }
    
        func changeColor(color: UIColor) -> UIImage {
            let backgroundSize = self.size
            UIGraphicsBeginImageContext(backgroundSize)
            guard let context = UIGraphicsGetCurrentContext() else {
                return self
            }
            var backgroundRect = CGRect()
            backgroundRect.size = backgroundSize
            backgroundRect.origin.x = 0
            backgroundRect.origin.y = 0
    
            var red: CGFloat = 0
            var green: CGFloat = 0
            var blue: CGFloat = 0
            var alpha: CGFloat = 0
            color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
            context.setFillColor(red: red, green: green, blue: blue, alpha: alpha)
            context.translateBy(x: 0, y: backgroundSize.height)
            context.scaleBy(x: 1.0, y: -1.0)
            context.clip(to: CGRect(x: 0.0, y: 0.0, width: self.size.width, height: self.size.height),
                     mask: self.cgImage!)
            context.fill(backgroundRect)
    
            var imageRect = CGRect()
            imageRect.size = self.size
            imageRect.origin.x = (backgroundSize.width - self.size.width) / 2
            imageRect.origin.y = (backgroundSize.height - self.size.height) / 2
    
            context.setBlendMode(.multiply)
            context.draw(self.cgImage!, in: imageRect)
    
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return newImage!
        }
    
    }
    
    let image = UIImage(named: "sample_image")
    imageView.image = image.changeTintColor(color: UIColor.red)
    
    func imageWithColor(color: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        color.setFill()
    
        let context = UIGraphicsGetCurrentContext()! as CGContext
        context.translateBy(x: 0, y: self.size.height)
        context.scaleBy(x: 1.0, y: -1.0);
        context.setBlendMode(.normal)
    
        let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) as CGRect
        context.clip(to: rect, mask: self.cgImage!)
        context.fill(rect)
    
        let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
        UIGraphicsEndImageContext()
    
        return newImage
    }
    
    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)
    
        let image = SVGKImage(named: "iconName")
        let svgIMGV = SVGKFastImageView(frame: self.imgView.frame)
             svgIMGV.image = image
              svgIMGV.fillTintColor(colorImage: UIColor.red, iconID: "Bank")
    
    // Add in extension SVGKImageView
    extension SVGKImageView {
     func fillTintColor(colorImage: UIColor, iconID: String) {
            if self.image != nil && self.image.caLayerTree != nil {
                print(self.image.caLayerTree.sublayers)
                guard let sublayers = self.image.caLayerTree.sublayers else { return }
                fillRecursively(sublayers: sublayers, color: colorImage, iconID: iconID)
            }
        }
    
         private func fillRecursively(sublayers: [CALayer], color: UIColor, iconID: String, hasFoundLayer: Bool) {
            var isLayerFound = false
            for layer in sublayers {
                if let l = layer as? CAShapeLayer {
    
                    print(l.name)                
                    //IF you want to color the specific shapelayer by id else remove the l.name  == "myID"  validation
                    if let name =  l.name,  hasFoundLayer == true && name == "myID" {
                        self.colorThatImageWIthColor(color: color, layer: l)
                        print("Colouring FInished")
                    }
                } else {
                    if layer.name == iconID {
                        if let innerSublayer = layer.sublayers as? [CAShapeLayer] {
                            fillRecursively(sublayers: innerSublayer, color: color, iconID: iconID, hasFoundLayer: true )
                            print("FOund")
                        }
                    } else {
                        if let l = layer as? CALayer, let sub = l.sublayers {
                            fillRecursively(sublayers: sub, color: color, iconID: iconID, hasFoundLayer: false)
                        }
                    }
                }
    
            }
        }
    
        func colorThatImageWIthColor(color: UIColor, layer: CAShapeLayer) {
            if layer.strokeColor != nil {
                layer.strokeColor = color.cgColor
            }
            if layer.fillColor != nil {
                layer.fillColor = color.cgColor
            }
        }
    
    }
    
    let navHeight = self.navigationController?.navigationBar.frame.height;
    let menuBtn = UIButton(type: .custom)
    menuBtn.frame = CGRect(x: 0, y: 0, width: 45, height: navHeight!)     
    menuBtn.setImage(UIImage(named:"image_name")!.withRenderingMode(.alwaysTemplate), for: .normal)        
    menuBtn.tintColor = .black
    
    let image = UIImage(named: "Heart")?.withRenderingMode(.alwaysTemplate)
    if #available(iOS 13.0, *) {
       imageView.image = image?.withTintColor(UIColor.white)
    }
    
    extension UIImage {
      func withBackground(color: UIColor, fill fillColor: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, true, scale)
        
        guard let ctx = UIGraphicsGetCurrentContext(), let image = cgImage else { return self }
        defer { UIGraphicsEndImageContext() }
        
        ctx.concatenate(CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: size.height))
        
        let rect = CGRect(origin: .zero, size: size)
        
        // draw background
        ctx.setFillColor(color.cgColor)
        ctx.fill(rect)
        
        // draw image with fill color
        ctx.clip(to: rect, mask: image)
        ctx.setFillColor(fillColor.cgColor)
        ctx.fill(rect)
        
        return UIGraphicsGetImageFromCurrentImageContext() ?? self
      }
    }
    
    let image = yourImage.withTintColor(.systemRed)
    
    let image = UIImage(named: "imageName")?.withTintColor(.white, renderingMode: .alwaysTemplate)
    
    extension UIImageView {
    
    func setImageTintColor(_ color: UIColor) {
        let tintedImage = self.image?.withRenderingMode(.alwaysTemplate)
        self.image = tintedImage
        self.tintColor = color
      }
    }
    
    myImageView.setImageTintColor(.systemBlue)