web-dev-qa-db-ja.com

ストーリーボード/ xibファイルからUIImage renderingModeを変更します

ストーリーボードまたはxibエディターからUIImagerenderingModeを変更することはできますか?

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

85

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

enter image description here

97
Snowman

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

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

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

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

Screenshot of Xcode showing attributes inspector for an image

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

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

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

IOS 7

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

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

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つだけです。

42
0xced

ストーリーボードで濃淡色を使用するようにimageView RenderingModeを設定すると、1ライナーに減らすことができます。

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

次に、画像と色合いをすべてストーリーボードで設定できます。

15
middleseatman

拡張機能で.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年ほど前から存在しています。

12
nikans

renderingModeまたはstoryboardからxibを設定することはできません。プログラムでアクセスできます。

例:

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

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
    }

}
8
Dmitry Coolerov

修正はとても簡単です

クラスImageView PDFを作成して、ストーリーボードで使用するだけです

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
4
Igor Popov

別の解決策は、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に設定します。

3

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で正常に動作します

2
Rodrigo

IOS 9では、Interface BuilderのtintColorプロパティの設定はまだバグがあります。

ImageViewプロパティを直接変更する行を記述する以外の実用的なソリューションは、アセットカタログでRender As:Template Imageを設定し、たとえば以下を呼び出すことです。

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

クレイジーなこのバグはまだiOS 12.1にあります!ストーリーボード/ xibsの場合:UIImageViewにタグを追加すると簡単に修正できます。

Swift 4.2

view.viewWithTag(1)?.tintColorDidChange()
0
Jayden Irwin

IBOutletを作成する場合、awakeFromNibメソッドで次のように変更できます。

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

@Mobyの答えはより正確ですが、これはもっと簡潔かもしれません。

0
amergin

インターフェースビルダーにランタイム属性tintColorを追加することで、この問題を修正しました。

注:Images.xcassetsファイルでテンプレート画像としてレンダリングされるように画像を設定する必要があります。

enter image description here

0
Sunil Targe