それは変更することが可能となるUIImage
のをrenderingMode
ストーリーボードまたはXIBエディタから?
目標はtintColor
、特定のUIImageView
オブジェクトに適用することです。
それは変更することが可能となるUIImage
のをrenderingMode
ストーリーボードまたはXIBエディタから?
目標はtintColor
、特定のUIImageView
オブジェクトに適用することです。
回答:
.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で、ランタイム属性を追加します。
画像レンダリングモードは、.xib
ファイルではなく.xcassets
ライブラリで設定できます。
アセットライブラリに画像を追加した後、画像を選択し、Xcodeの右側にある属性インスペクターを開きます。「Render As」属性を見つけて、「template」に設定します。
画像のレンダリングモードを設定した後UIImageView
、.xib
または.storyboard
ファイルのにティントカラーを追加して、画像の色を調整できます。
これは、1つのインターフェイスビルダーファイルだけでなく、使用される場所に関係なく画像のプロパティを設定しますが、ほとんどすべての場合(私が遭遇した場合)、これは必要な動作です。
注意すべきいくつかの点:
UIImageView
。私はそれについて詳しく調べていません。UIKitComponents
の画像のようなUIButton
のやUIBarButtonItem
さん。UIImageView
、アプリを実行すると色合いが常に表示されるとは限りません。
ストーリーボードまたはxibのUIImageViewでテンプレートレンダリングモードを使用すると、iOS 7とiOS 8の両方で非常にバグが多くなります。
UIImageがストーリーボード/ xibから正しくデコードされません。メソッドのimageView.image.renderingMode
プロパティを調べると、xcassetsファイルでRender As Template Imageに設定した場合viewDidLoad
でもUIImageRenderingModeAutomatic
、常にであることがわかります。
回避策として、手動でレンダリングモードを設定する必要があります。
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImageは適切にデコードされ、そのrenderingMode
プロパティはxcassetsファイルで選択されたものを反映しますが、画像は着色されていません。
回避策として、2つのオプションがあります。
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つだけです。
拡張子で.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年前から存在しています。
またはrenderingMode
からは設定できません。プログラムでアクセスできます。storyboard
xib
例:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
ストーリーボードで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
}
}
修正は非常に簡単です
クラス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
別の解決策はUIImageView
サブクラスを作成することです:
final class TemplateImageView: UIImageView {
override func awakeFromNib() {
super.awakeFromNib()
guard let oldImage = image else { return }
image = nil
image = oldImage.withRenderingMode(.alwaysTemplate)
}
}
次に、インターフェイスビルダーでクラスをに設定しTemplateImageView
ます。
ストーリーボードから設定する簡単な方法:
@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で正常に動作します
IBOutletを作成する場合は、awakeFromNibメソッドで次のように変更できます...
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
@Mobyの答えはより正確ですが、これはより簡潔かもしれません。
クレイジーこのバグはまだiOS 12.1にあります!ストーリーボード/ xibsの場合:UIImageViewにタグを追加すると、簡単に修正できます。
Swift 4.2
view.viewWithTag(1)?.tintColorDidChange()
extension UIImageView {
@IBInspectable var renderModeTemplate : Bool {
get{
return image?.renderingMode == .alwaysTemplate
}
set{
image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
}
}
}
ストーリーボードでUIImageViewを選択し、インスペクターを選択して、プロパティをrenderModeTemplate
= Storyboardに設定します。On