从情节提要/ xib文件修改UIImage renderingMode


Answers:


101

您可以在.xib或情节提要文件中执行以下操作:

(OBJ-C)在上创建一个类别UIImageView

@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

(快速4)为UIImageView以下项创建扩展名:

extension UIImageView {
    func setImageRenderingMode(_ renderMode: UIImage.RenderingMode) {
        assert(image != nil, "Image must be set before setting rendering mode")
        // AlwaysOriginal as an example
        image = image?.withRenderingMode(.alwaysOriginal)
    }
}

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

在此处输入图片说明


44
我喜欢这个答案,因为它是对这个问题的答案。

1
我宁愿创建UIImageView子类,也不愿进行键值设置。因为这样更容易设置,所以我们可以避免将数字设置为枚举值。例如:`@implementation TemplateRenderingImageView-(id)initWithCoder:(NSCoder *)aDecoder {self = [super initWithCoder:aDecoder]; 如果(self){self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 自我回报;} @ end`
john fantasy

1
好答案!屏幕截图很有帮助。
BigSauce 2014年

1
当然不能与Launch Screen.xib一起使用,因为您不能将其与用户定义的运行时属性一起使用。
史蒂夫·摩瑟

3
硬编码2作为值是坏还是不好。使用xcassets目录是正确的答案。
tGilani

198

您可以不在.xib文件中而是在.xcassets库中设置图像渲染模式。

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

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

这会在图像的使用位置(而不是仅在一个界面生成器文件中)设置属性,但是在几乎所有情况下(我已经遇到),这都是您想要的行为。

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

注意事项:

  • 图像颜色在界面生成器中似乎没有更改(从Xcode 6.1.1开始),但是在运行应用程序时可以使用。
  • 我在使用此功能时遇到了一些麻烦,在某些情况下,我必须删除并重新添加UIImageView。我还没有深入研究。
  • 这也对其他的伟大工程,UIKitComponents为图像,UIButton年代和UIBarButtonItem的。
  • 如果您有一堆在资产库中不可见的白色图像,将它们设置为黑色/透明图像并更改渲染模式将使您的生活提高10倍。

15
似乎有一个色调颜色存在错误UIImageView,因此在运行应用程序时并非总是显示色调颜色。
2015年

@Fogh我也遇到了一些类似的错误。通过编程设置色调颜色是否可以解决此问题?
Anthony Mattox

2
我可以确认在IB中设置色调颜色时存在问题。以编程方式进行设置即可。我为此提交了一个错误#20305518。
Nikolay Derkach 2015年

1
@AxelGuilmin是的。实际上,仅使用Alpha通道,因此只要您想要透明度,它就可以是任何颜色。
Anthony Mattox

1
现在可以在Xcode 7.3(7D175)中使用!尽管接受的答案是非常直观的解决方法,但我更喜欢此答案。
nstein

43

在iOS 7和iOS 8上,在情节提要或xib中将模板渲染模式与UIImageView一起使用非常容易出错。

在iOS 7上

UIImage没有从情节提要/ xib正确解码。如果检查方法中的imageView.image.renderingMode属性,即使将其设置为xcassets文件中的“ 作为模板图像渲染”viewDidLoad,也会注意到它始终是。UIImageRenderingModeAutomatic

要解决此问题,您必须手动设置渲染模式:

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

在iOS 8上

UIImage已正确解码,其renderingMode属性反映了在xcassets文件中选择的内容,但图像未着色。

要解决此问题,您有两种选择:

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

要么

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

您可以选择自己喜欢的选项,都可以正确着色图像。

(如果您正在使用Xcode 6.2进行编译,则只需这样做self.imageView.tintColor = self.imageView.tintColor;就足够了,但是如果您正在使用Xcode 6.3进行编译,那么它将不再起作用)

结论

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


2
谢谢。唯一的解决办法#2在Xcode 7和iOS为我工作8
萨弗里德

3
我确认为iOS 8的解决方法也是valable于iOS 9
迈克尔Pirotte

1
我肯定在Xcode 7上看到了同样的事情-用户属性的解决方法很好。谢谢!
杰弗里·怀斯曼

在awakeFromNib中手动重置tintColor做到了!(该图像也已在.xcassets目录中设置为模板,否则您必须从原始图像制作一个模板图像)。谢谢!!
horseshoe7

15

可以将imageView RenderingMode设置为使用情节提要中的色调颜色可以简化为单一格式:

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

然后,可以在情节提要中设置图像和色调的颜色。


13

您可以使用扩展名解决.xib问题:

import UIKit

// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
    override open func awakeFromNib() {
        super.awakeFromNib()
        self.tintColorDidChange()
    }
}

资料来源:https : //gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac

令人惊讶的是,此错误已经存在了大约4-5年。


3
应该选择它作为答案
farzadshbfn

仍然是一个错误,并且从iOS 12.0起仍可以修复。
山姆·索菲斯

在iOS的12.1仍然是一个错误
塞萨尔

虚幻的家伙,虚幻。

8

renderingMode无法通过storyboard或进行设置xib。它可以通过编程方式访问。

例如:

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

3
我认为,您在代码中打了一些小错字。第二行应该是UIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Artem Stepanenko 2013年

8

在情节提要中设置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
    }

}

这是解决新问题的唯一答案。谢谢。
西蒙·莫申科

出于某种奇怪的原因对我不起作用...是否应该更新情节提要中的颜色?
切萨雷

4

修复起来很容易

只需创建类UIImageViewPDF并将其在情节提要中使用

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

3

另一个解决方案是创建一个UIImageView子类:

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

然后只需将“接口生成器”中的类设置为即可TemplateImageView


最好的解决方案!
Irshad Mohamed

2

通过情节提要设置的简单方法:

@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上正常运行


1

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

请注意,除了编写直接修改ImageView属性的行以外,一种可行的解决方案是在资产目录中设置“渲染为:模板图像”,然后调用例如:

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

1

我通过tintColor在界面生成器中添加运行时属性来解决此问题。

注意:您仍然需要将图像设置为在Images.xcassets文件中作为模板图像呈现。

在此处输入图片说明


0

如果创建IBOutlet,则可以像这样在awakeFromNib方法中对其进行更改...

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

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


1
问题是如何在情节提要(或xib)中而不是在代码中执行此操作。
Artem Stepanenko 2014年

@artem-是的,很抱歉,我不是要推断我对您的问题有答案。仅仅指出了通过IBOutlet处理此问题的简单方法
2014年

0

疯狂,此错误仍在iOS 12.1中!对于情节提要/ xib:将标签添加到UIImageView可以快速解决。

斯威夫特4.2

view.viewWithTag(1)?.tintColorDidChange()

0
extension UIImageView {

   @IBInspectable var renderModeTemplate : Bool {
       get{
           return image?.renderingMode == .alwaysTemplate
       }

       set{
          image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
       }
   }
}

在情节提要中选择UIImageView并选择检查器,设置属性renderModeTemplate= On 在情节提要中

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.