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

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


当前回答

profileImageView。image = theImageView.image!.withRenderingMode(.alwaysTemplate) profileImageView。tintColor = uiccolor .green

OR

首先在图像资产中选择特定图像,然后选择红色作为模板而不是默认,然后写行。 profileImageView。tintColor = uiccolor .green

其他回答

另外,对于以上的答案,在iOS 13及以后有一个干净的方法

let image = UIImage(named: "imageName")?.withTintColor(.white, renderingMode: .alwaysTemplate)

这是我的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函数来改变图像的颜色

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

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

您必须将图像添加到WatchKit应用程序中的资产目录,并将图像集设置为在属性检查器中呈现为模板图像。与iPhone应用程序不同,您目前不能在WatchKit扩展的代码中设置模板渲染。 设置该图像用于你的WKInterfaceImage在界面生成器为你的应用程序 创建一个IBOutlet在你的WKInterfaceController为WKInterfaceImage称为“theImage”…

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

theImage.setTintColor(UIColor.red)

斯威夫特2:

theImage.setTintColor(UIColor.redColor())

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

[self.theImage setTintColor:[UIColor redColor]];

如果您使用模板图像并且没有应用着色颜色,则将应用WatchKit应用程序的全局着色。如果你没有设置全局色调,当作为模板图像使用时,图像将默认为浅蓝色。

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

如果您有SVG图像的任何id,您可以根据id填充颜色。

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

}

或者签出这个例子。

https://github.com/ravisfortune/SVGDEMO