从storyboard / xib文件修改UIImage renderingMode

时间:2013-10-22 12:02:49

标签: ios ios7 xcode-storyboard

是否可以从故事板或xib编辑器修改UIImage的{​​{1}}?

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

16 个答案:

答案 0 :(得分:180)

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

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

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

这会在图像上设置属性,而不是仅仅在一个界面构建器文件中,但在几乎所有情况下(我遇到过),这都是您想要的行为。

Screenshot of Xcode showing attributes inspector for an image

有几点需要注意:

  • 图像颜色在界面构建器中似乎没有变化(从Xcode 6.1.1开始),但在应用程序运行时会起作用。
  • 我在使用此功能时遇到了一些烦恼,在某些情况下,我必须删除并重新添加UIImageView。我没有深入研究过。
  • 这也适用于其他UIKitComponents,例如UIButtonUIBarButtonItem中的图片。
  • 如果您有一堆在资产库中不可见的白色图像,将它们设置为黑色/透明图像并更改渲染模式将使您的生活提高10倍。

答案 1 :(得分:96)

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

(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

(Swift 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中,添加运行时属性:

enter image description here

答案 2 :(得分:42)

在故事板或xib中使用模板渲染模式和UIImageView是非常错误的,无论是在iOS 7还是iOS 8上。

在iOS 7上

未从storyboard / xib中正确解码UIImage。如果您检查imageView.image.renderingMode方法中的viewDidLoad属性,即使您将其设置为渲染为模板图像,您也会注意到它始终是UIImageRenderingModeAutomatic你的xcassets文件。

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

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

在iOS 8上

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

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

  1. 用户定义的运行时属性中设置tintColor属性,而不是属性检查器窗格。
    1. 手动重置tintColor:
    2. 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,则只需要一种解决方法。

答案 3 :(得分:15)

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

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

然后可以在故事板中设置图像和色调颜色。

答案 4 :(得分:10)

您可以使用扩展程序修复.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

太棒了,这个bug已经存在了4到5年了。

答案 5 :(得分:8)

您无法从renderingModestoryboard设置xib。它可以通过编程方式访问。

前:

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

答案 6 :(得分:8)

设置tintColor&故事板中的课程。

//
//  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
    }

}

答案 7 :(得分: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

答案 8 :(得分:3)

另一个解决方案是创建一个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

答案 9 :(得分:2)

从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

答案 10 :(得分:1)

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

请注意,除了直接修改ImageView属性的写行之外,工作解决方案是在资产目录中设置Render As:Template Image,并调用例如:

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

答案 11 :(得分:0)

如果您创建了一个IBOutlet,您可以在awakeFromNib方法中更改它,就像这样......

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

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

答案 12 :(得分:0)

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

Swift 4.2

view.viewWithTag(1)?.tintColorDidChange()

答案 13 :(得分:0)

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

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

enter image description here

答案 14 :(得分:0)

extension UIImageView {

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

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

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

答案 15 :(得分:0)

正如鲁道夫也提到above,我将定义一个简单的类,如下所示:

import UIKit

@IBDesignable class TintImage: UIImageView{
    override func layoutSubviews() {
        super.layoutSubviews()
 
        image = image?.withRenderingMode(.alwaysTemplate)
    }
}

在此定义之后,只需将图像视图添加到情节提要,然后选择其自定义类为TintImage。这将激活情节提要中的“色调”选择。