ストーリーボード/ xibファイルからUIImageレンダリングモードを変更する


93

それは変更することが可能となるUIImageのをrenderingModeストーリーボードまたはXIBエディタから?

目標はtintColor、特定のUIImageViewオブジェクトに適用することです。

回答:


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

(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で、ランタイム属性を追加します。

ここに画像の説明を入力してください


44
私がこの答えで気に入っているのは、それが質問に対する答えであることです。
藻類、2014

1
キーの値を設定するのではなく、UIImageViewサブクラスを作成したいと思います。なぜなら、これでセットアップが簡単になり、列挙値への数値設定を回避できるからです。例: `@implementation TemplateRenderingImageView-(id)initWithCoder:(NSCoder *)aDecoder {self = [super initWithCoder:aDecoder]; if(self){self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; }自分自身を返す。} @ end`
ジョンファンタジー

1
正解です。スクリーンショットは役に立ちました。
BigSauce、2014

1
もちろん、Launch Screen.xibでは機能しません。ユーザー定義のランタイム属性を使用できないためです。
Steve Moser

3
値として2をハードコーディングするのは悪い悪い悪い悪い.. xcassetsカタログの使用は正しい答えです。
tGilani 2015

198

画像レンダリングモードは、.xibファイルではなく.xcassetsライブラリで設定できます。

アセットライブラリに画像を追加した後、画像を選択し、Xcodeの右側にある属性インスペクターを開きます。「Render As」属性を見つけて、「template」に設定します。

画像のレンダリングモードを設定した後UIImageView.xibまたは.storyboardファイルのにティントカラーを追加して、画像の色を調整できます。

これは、1つのインターフェイスビルダーファイルだけでなく、使用される場所に関係なく画像のプロパティを設定しますが、ほとんどすべての場合(私が遭遇した場合)、これは必要な動作です。

画像の属性インスペクターを示すXcodeのスクリーンショット

注意すべきいくつかの点:

  • 画像の色はインターフェイスビルダー(Xcode 6.1.1以降)では変更されていないように見えますが、アプリケーションの実行時に機能します。
  • この機能でバグが発生し、状況によってはを削除して再度追加する必要がありましたUIImageView。私はそれについて詳しく調べていません。
  • これは、他に素晴らしい作品UIKitComponentsの画像のようなUIButtonのやUIBarButtonItemさん。
  • アセットライブラリに表示されない白い画像がたくさんある場合は、それらを黒/透明な画像にしてレンダリングモードを変更すると、最大で10倍の寿命になります。

15
上の色合いにはバグがあるように見えるためUIImageView、アプリを実行すると色合いが常に表示されるとは限りません。
Fogh

@Foghそのようないくつかの一貫性のないバグもありました。ティントカラーを設定すると、プログラムでこれを修正できますか?
Anthony Mattox、

2
IBで色合いを設定する際に問題があることが確認できました。プログラムで設定すると機能します。バグ#20305518を提出しました。
Nikolay Derkach 2015年

1
@AxelGuilminうん。実際にはアルファチャネルのみが使用されるため、透明度が必要な色であれば、どの色でもかまいません。
Anthony Mattox 2016

1
Xcode 7.3(7D175)で動作します!受け入れられた答えは非常に直感的な回避策ですが、私は代わりにこの答えを好みます。
nstein

43

ストーリーボードまたはxibのUIImageViewでテンプレートレンダリングモードを使用すると、iOS 7とiOS 8の両方で非常にバグが多くなります。

iOS 7の場合

UIImageがストーリーボード/ xibから正しくデコードされません。メソッドのimageView.image.renderingModeプロパティを調べると、xcassetsファイルでRender As Template Imageに設定した場合viewDidLoadでもUIImageRenderingModeAutomatic、常にであることがわかります。

回避策として、手動でレンダリングモードを設定する必要があります。

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

iOS 8の場合

UIImageは適切にデコードされ、そのrenderingModeプロパティはxcassetsファイルで選択されたものを反映しますが、画像は着色されていません。

回避策として、2つのオプションがあります。

  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のみをサポートする必要がある場合、必要な回避策は1つだけです。


2
ありがとう。Xcodeの7とiOS 8で私のために働いているだけ#2を回避
サーフライダー

3
私は、iOS 8のための回避策は、iOS版9.のためにもvalableであることを確認
マイケルPirotte

1
Xcode 7でも同じことが確実に見られます-ユーザー属性の回避策は問題ありませんでした。ありがとう!
ジェフリーワイズマン2016

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でも修正されます。
Sam Soffes

それでもiOS 12.1のバグ
Cesare

非現実的な男、非現実的。
マット

8

またはrenderingModeからは設定できません。プログラムでアクセスできます。storyboardxib

例:

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

3
私はあなたがあなたのコードに小さなタイプミスをしたと思います。2行目はUIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
アルテムステパネンコ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
    }

}

これは、新しい迅速に動作した唯一の答えです。ありがとうございました。
Simon Moshenko 2017年

変な理由で動作しません...ストーリーボードの色を更新するのですか?
チェザーレ

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 2017

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プロパティを直接変更する行を書く以外の実用的な解決策は、アセットカタログでRender As:Template Imageを設定して、たとえば次のように呼び出すことです。

[[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にあります!ストーリーボード/ xibsの場合:UIImageViewにタグを追加すると、簡単に修正できます。

Swift 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= Storyboardに設定します。On

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.