我有一个名为theImageView的UIImageView, UIImage是单色的(透明背景),就像下面左边的黑色心形。我如何在iOS 7或更高的系统中,根据iOS 7+导航栏图标中使用的色调方法,以编程方式更改此图像的色调颜色?
这个方法也适用于WatchKit的Apple Watch应用程序吗?
我有一个名为theImageView的UIImageView, UIImage是单色的(透明背景),就像下面左边的黑色心形。我如何在iOS 7或更高的系统中,根据iOS 7+导航栏图标中使用的色调方法,以编程方式更改此图像的色调颜色?
这个方法也适用于WatchKit的Apple Watch应用程序吗?
当前回答
试试这个
http://robots.thoughtbot.com/designing-for-ios-blending-modes
or
- (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];
}
其他回答
斯威夫特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]];
我必须在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):
试试这个
http://robots.thoughtbot.com/designing-for-ios-blending-modes
or
- (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];
}
如果您有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