从storyboard / xib文件修改UIImage renderingMode

是否有可能从故事板或xib编辑器修改UIImagerenderingMode

目标是将tintColor应用于特定的UIImageView对象。

以下是如何在.xib或storyboard文件中执行此操作的方法:

UIImageView上创build一个类别:

 @interface UIImageView (Utils) - (void)setImageRenderingMode:(UIImageRenderingMode)renderMode; @end @implementation UIImageView (Utils) - (void)setImageRenderingMode:(UIImageRenderingMode)renderMode { NSAssert(self.image, @"Image must be set before setting rendering mode"); self.image = [self.image imageWithRenderingMode:renderMode]; } @end 

然后在xib文件的Identity Inspector中添加一个运行时属性:

在这里输入图像说明

您可以将图像呈现模式设置为不在.xcassets文件中,而是在.xcassets库中。

将图像添加到资产库后,select图像并打开Xcode右侧的属性检查器。 find属性“渲染为”并将其设置为“模板”。

设置图像的渲染模式后,可以在.storyboard.storyboard文件的UIImageView中添加色调来调整图像的颜色。

这将设置图像上的属性,而不仅仅是在一个接口生成器文件中,但几乎在所有情况下(我遇到过),这是你想要的行为。

Xcode的屏幕截图显示了图像的属性检查器

有几件事要注意:

  • 图像颜色在界面生成器中看起来并没有改变(从Xcode 6.1.1开始),但是在应用程序运行时会起作用。
  • 我经历了这个function的一些bugginess,在一些情况下,我不得不删除并重新添加UIImageView 。 我没有深究。
  • 这也适用于其他UIKitComponentsUIButtonUIBarButtonItem的图像。
  • 如果您的资产库中有一堆不可见的白色图像,使它们成为黑色/透明图像并更改渲染模式将使您的生活质量提高10倍。

在iOS 7和iOS 8上,在故事板或xib中将UIImageView用于模板呈现模式非常麻烦。

在iOS 7上

UIImage没有从故事板/ xib正确解码。 如果您在viewDidLoad方法中检查了UIImageRenderingModeAutomatic ,即使将其设置为“在xcassets文件中渲染为模板图像” ,您也会注意到它始终是UIImageRenderingModeAutomatic。

要解决方法,您必须手动设置呈现模式:

 self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 

在iOS 8上

UIImage被正确解码,其renderingMode属性反映了在xcassets文件中select的内容,但图像没有着色。

要解决这个问题,你有两个select:

  1. 在“ 用户定义的运行时属性”中设置tintColor属性,而不是“属性”检查器窗格。

要么

  1. 手动重置tintColor:
 UIColor *tintColor = self.imageView.tintColor; self.imageView.tintColor = nil; self.imageView.tintColor = tintColor; 

你可以select你喜欢的选项,都适当的色调图像。

(如果使用Xcode 6.2进行编译,只需执行self.imageView.tintColor = self.imageView.tintColor;就足够了,但如果使用Xcode 6.3进行编译,则不再有效)

结论

如果您需要同时支持iOS 7和iOS 8,则需要两种解决方法。 如果您只需要支持iOS 8,则只需要一个解决方法。

设置imageView RenderingMode使用故事板中的色调颜色可以简化为一行:

 [self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]]; 

然后,图像和色彩的颜色都可以在故事板中设置。

你不能从storyboardxib设置renderingMode 。 它可以通过程序访问。

例如:

 UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"]; selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 

在Storyboard中设置tintColor&Class。

 // // TintColoredImageView.swift // TintColoredImageView // // Created by Dmitry Utmanov on 14/07/16. // Copyright © 2016 Dmitry Utmanov. All rights reserved. // import UIKit @IBDesignable class TintColoredImageView: UIImageView { override var image: UIImage? { didSet { let _tintColor = self.tintColor self.tintColor = nil self.tintColor = _tintColor } } override init(frame: CGRect) { super.init(frame: frame) initialize() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) initialize() } override init(image: UIImage?) { super.init(image: image) initialize() } override init(image: UIImage?, highlightedImage: UIImage?) { super.init(image: image, highlightedImage: highlightedImage) initialize() } func initialize() { let _tintColor = self.tintColor self.tintColor = nil self.tintColor = _tintColor } } 

这很容易修复

只需创buildUIImageViewPDF类并在故事板中使用它

 IB_DESIGNABLE @interface UIImageViewPDF : UIImageView @end @implementation UIImageViewPDF - (void) didMoveToSuperview { [super didMoveToSuperview]; self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; id color = self.tintColor; self.tintColor = color; } @end 

另一个解决scheme是创build一个UIImageView子类:

 final class TemplateImageView: UIImageView { override func awakeFromNib() { super.awakeFromNib() guard let oldImage = image else { return } image = nil image = oldImage.withRenderingMode(.alwaysTemplate) } } 

然后,只需将Interface Builder中的类设置为TemplateImageView

在iOS 9中,在Interface Builder中设置tintColor属性仍然有问题。

请注意,除了直接修改ImageView属性之外,一个工作解决scheme是在资产目录中设置“渲染为:模板图像”,然后调用例如:

 [[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]]; 

如果你创build一个IBOutlet,你可以在你的awakeFromNib方法中改变它,像这样…

 self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 

虽然@ Moby的答案是更正确的 – 这可能会更简洁。

从Storyboard设置简单的方法:

 @IBDesignable public class CustomImageView: UIImageView { @IBInspectable var alwaysTemplate: Bool = false { didSet { if alwaysTemplate { self.image = self.image?.withRenderingMode(.alwaysTemplate) } else { self.image = self.image?.withRenderingMode(.alwaysOriginal) } } } } 

在iOS 10和Swift 3上运行良好