我有一个名为theImageView的UIImageView, UIImage是单色的(透明背景),就像下面左边的黑色心形。我如何在iOS 7或更高的系统中,根据iOS 7+导航栏图标中使用的色调方法,以编程方式更改此图像的色调颜色?
这个方法也适用于WatchKit的Apple Watch应用程序吗?
我有一个名为theImageView的UIImageView, UIImage是单色的(透明背景),就像下面左边的黑色心形。我如何在iOS 7或更高的系统中,根据iOS 7+导航栏图标中使用的色调方法,以编程方式更改此图像的色调颜色?
这个方法也适用于WatchKit的Apple Watch应用程序吗?
当前回答
iOS
解决方案从接口生成器,设置templateImage参数在keyPath和选择您的色调颜色从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
}
}
}
其他回答
斯威夫特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
}
}
改变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
改变图片的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!
}
}
这里有一个类别应该可以做到这一点
@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]];
这是我的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函数来改变图像的颜色
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
另外,对于以上的答案,在iOS 13及以后有一个干净的方法
let image = UIImage(named: "imageName")?.withTintColor(.white, renderingMode: .alwaysTemplate)