我有一个名为theImageView的UIImageView, UIImage是单色的(透明背景),就像下面左边的黑色心形。我如何在iOS 7或更高的系统中,根据iOS 7+导航栏图标中使用的色调方法,以编程方式更改此图像的色调颜色?
这个方法也适用于WatchKit的Apple Watch应用程序吗?
我有一个名为theImageView的UIImageView, UIImage是单色的(透明背景),就像下面左边的黑色心形。我如何在iOS 7或更高的系统中,根据iOS 7+导航栏图标中使用的色调方法,以编程方式更改此图像的色调颜色?
这个方法也适用于WatchKit的Apple Watch应用程序吗?
当前回答
这是我的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函数来改变图像的颜色
其他回答
斯威夫特5
重绘图像的背景和填充颜色
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
}
}
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应用程序的全局着色。如果你没有设置全局色调,当作为模板图像使用时,图像将默认为浅蓝色。
自iOS 13以来,UIImage有一个原生方法
let image = yourImage.withTintColor(.systemRed)
你可以在Swift 3中使用它,如果你有一个图像来替换清除按钮
func addTextfieldRightView(){
let rightViewWidth:CGFloat = 30
let viewMax = self.searchTxt.frame.height
let buttonMax = self.searchTxt.frame.height - 16
let buttonView = UIView(frame: CGRect(
x: self.searchTxt.frame.width - rightViewWidth,
y: 0,
width: viewMax,
height: viewMax))
let myButton = UIButton(frame: CGRect(
x: (viewMax - buttonMax) / 2,
y: (viewMax - buttonMax) / 2,
width: buttonMax,
height: buttonMax))
myButton.setImage(UIImage(named: "BlueClear")!, for: .normal)
buttonView.addSubview(myButton)
let clearPressed = UITapGestureRecognizer(target: self, action: #selector(SearchVC.clearPressed(sender:)))
buttonView.isUserInteractionEnabled = true
buttonView.addGestureRecognizer(clearPressed)
myButton.addTarget(self, action: #selector(SearchVC.clearPressed(sender:)), for: .touchUpInside)
self.searchTxt.rightView = buttonView
self.searchTxt.rightViewMode = .whileEditing
}
我必须在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
}
}
用法:
theImageView。image = theImageView.image.imageWithColor(uiccolor . 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!
}
}
用法:
theImageView。image = theImageView.image?imageWithColor (color1 UIColor.red):