Как изменить tintcolor изображения в iOS и WatchKit
У меня есть UIImageView под названием "theImageView", с UIImage в одном цвете (прозрачный фон), как и левое черное сердце ниже. Как я могу изменить цвет оттенка этого изображения программно в iOS 7 или выше, в соответствии с методом оттенка, используемым в значках панели навигации iOS 7+?
может ли этот метод также работать в WatchKit для приложения Apple Watch?
18 ответов
iOS
Для приложения iOS в Swift 3 или 4:
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
В WatchKit для приложений Apple Watch вы можете установить оттенок цвета для изображения шаблона.
- необходимо добавить изображение в каталог активов в приложении WatchKit и задать набор изображений для отображения в виде Изображение шаблона в Инспекторе атрибутов. В отличие от приложения для iPhone, вы не можете установить отображение шаблона в коде в расширении WatchKit в настоящее время.
- установите это изображение для использования в вашем WKInterfaceImage в interface builder для вашего приложения
- создайте IBOutlet в вашем WKInterfaceController для WKInterfaceImage под названием "theImage"...
чтобы затем установить цвет оттенка в Swift 3 или 4:
theImage.setTintColor(UIColor.red)
Swift 2:
theImage.setTintColor(UIColor.redColor())
чтобы затем установить цвет оттенка в Objective-C:
[self.theImage setTintColor:[UIColor redColor]];
если вы используете изображение шаблона и не применяете цвет оттенка, будет применен глобальный оттенок для вашего приложения WatchKit. Если вы не установили глобальный оттенок, theImage
будет окрашен в голубой цвет по умолчанию при использовании в качестве шаблона изображения.
вот категория, которая должна сделать трюк
@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
.
Я думал, что поделюсь, как я это сделал:
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(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!
}
}
использование:
theImageView.image = theImageView.image?.imageWithColor(color1: UIColor.red)
в раскадровке и средств изображения. вы также можете изменить эти два:
обновите режим рендеринга до шаблона
обновите цвет оттенка в представлениях.
изменение оттенка изображения (картинка, классические изображения, фото) использовать :
функция Tintimage Swift 3:
import UIKit
// 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)
}
}
/// Tint pictogram with color
/// Method work on single colors without fading, mainly for svg images
///
/// - Parameter fillColor: TintColor: Tint color
/// - Returns: Tinted image
public func tintPictogram(with fillColor: UIColor) -> UIImage {
return modifiedImage { context, rect in
// draw tint color
context.setBlendMode(.normal)
fillColor.setFill()
context.fill(rect)
// mask by alpha values of original image
context.setBlendMode(.destinationIn)
context.draw(cgImage!, 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!
}
}
}
изменение оттенка изображения (SVG, уникальный цвет) использовать, что с изображение шаблона в активе :
функция Tintpictogram Swift 3:
import UIKit
// MARK: - Extensions UIImage
public extension UIImage {
/// Tint pictogram with color
/// Method work on single colors without fading, mainly for svg images
///
/// - Parameter fillColor: TintColor: Tint color
/// - Returns: Tinted image
public func tintPictogram(with fillColor: UIColor) -> UIImage {
return modifiedImage { context, rect in
// draw tint color
context.setBlendMode(.normal)
fillColor.setFill()
context.fill(rect)
// mask by alpha values of original image
context.setBlendMode(.destinationIn)
context.draw(cgImage!, 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!
}
}
Если кто-нибудь решение без 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
}
}
С 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)
попробуй такое
http://robots.thoughtbot.com/designing-for-ios-blending-modes
или
- (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];
}
для swift 3 целей
theImageView.image = theImageView.image!.withRenderingMode(.alwaysTemplate)
theImageView.tintColor = UIColor.red
воспользуйтесь расширением в 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)
iOS
решение для этого из InterfaceBuilder,установить templateImage param в 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
}
}
}
теперь я использую этот метод, основанный на ответе Дункана Бэббиджа:
+ (UIImageView *) tintImageView: (UIImageView *)imageView withColor: (UIColor*) color{
imageView.image = [imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[imageView setTintColor:color];
return imageView;
}
вы можете использовать это в Swift 3, Если у вас есть изображение для замены кнопки clear
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
}
подкласс, который можно использовать из кода и построителя интерфейса:
@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
Это мое расширение 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
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
}
для тонирования изображения 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)
profileImageView.image = theImageView.изображение!.withRenderingMode(.alwaysTemplate)
profileImageView.tintColor = UIColor.зеленый
или
Сначала выберите конкретное изображение в Image asset, а затем выберите reddened как шаблон вместо Default и после этого напишите строку. profileImageView.tintColor = UIColor.зеленый