web-dev-qa-db-ja.com

UIImageViewは常にテンプレート画像に色合いを付けるとは限りません

以下の場合、同じ設定と同じテンプレート画像を持つ2つのUIImageViewがあります...しかし、1つは画像に色を付け、もう1つはしません

動作中のUIImageViewを複製し、他の代わりに配置して動作しました。これは私に何度も起こり、この解決策は常に機能しましたが、私はまだ何が間違っていたのだろうかと思いますか? Xcodeのバグになりますか?同様のことがあなたに起こりましたか? Xcode 8.1を使用しています。

Xcode screenshot

Xcode screenshot

46
Zuzana Paulis

簡単な解決策:

enter image description here

UIImageViewのtintColorを指定された色に設定し、画像が確実に色付けされるようにする新しいランタイム属性を追加します。

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

この方法では、追加のアウトレット、拡張機能、またはコード行は必要ありません。

また注意してください:ビュー上のtintColorが同じ色の場合、ユーザー定義属性のtintColorは適用されません。異なる必要があります。

112
David Rees

サブクラスや別のIBInspectable属性を必要としない最適なソリューション:

import UIKit

extension UIImageView {
    override open func awakeFromNib() {
        super.awakeFromNib()
        tintColorDidChange()
    }
}
48
allaire

問題は、null状態のない色合いの値に起因します(Storyboard/Interface Builder UI内)。 XcodeがUIImageViewに色合いを適用するかどうかを決定するために、追加のテストがあるようです。 Xcodeでは、明らかにこれはUIImageViewに適用される制約を評価することで行われます。私の知る限り、このテストは文書化されていません。

UIImageViewの2つ(または1つ)の側面に「最近傍への間隔」制約のみがある場合、UIImage.renderingModeに設定された値に関係なく色合いは適用されません。

UIImageViewの3つ(またはすべて)の側面に「最近傍への間隔」制約がある場合、UIImage.renderingMode.alwaysTemplateに設定されている場合、色合いが適用されます。

ストーリーボード/インターフェースビルダーのみのアプローチでは、画像をUIImage.renderingModeに設定し、画像をアセットカタログに追加してから、画像セットの[レンダリング]プロパティを[テンプレート画像]に変更します。

24
richardjsimkins

プログラムでtintColorを設定してみてください。それは私のために問題を修正しました。

UIImageViewにバグがあると思います。ストーリーボードで色合いを設定すると、アセットがテンプレートとしてレンダリングするように設定されていても、その色合いは適用されません。

回避策は、ストーリーボードのUIImageViewの親ビューに色合いを適用することです。

または、tintColorをnilに設定し、UIImageViewをアウトレットにバインドしてコードを再度戻します。

14
paddlefish

この拡張機能を使用して、インターフェイスビルダーからUIImageView tintColorを設定します。

extension UIImageView {
    @IBInspectable var imageColor: UIColor! {
        set {
            super.tintColor = newValue
        }
        get {
            return super.tintColor
        }
    }
} 
6
Mina

既存のUIImageViewを削除して新しいUIImageViewを追加すると、問題はなくなりました。どうやら、状況は、画像をAssetsフォルダーに追加した後にUIImageViewを追加する必要があるということです。

3
rudymatos

たぶん、私はまだ理解していない何かに気づくまで1時間頭を叩いていたので助けになるかもしれません。

.nibファイルにビューがあり、1つ(UIImageView)以外のすべてのアウトレットにはデフォルト以外の色合いがありました。すべての提案された答えを試しましたが、プログラムで変更した後、デフォルトの色合いを選択して問題を解決しました。

enter image description here

enter image description here

バグかもしれませんか?

3
Reimond Hill

ランタイム属性のトリックはうまくいきませんでした。私はこの種のものを修正するためだけにこのクラスを作成しました。問題のあるすべての画像ビューをこのクラスに設定するだけです。

final class TintedImageView: UIImageView {

    // WORKAROUND: Template images are not tinted when set using the Interface Builder.
    override func layoutSubviews() {
        super.layoutSubviews()
        let preferredTintColor = tintColor
        tintColor = nil
        tintColor = preferredTintColor
    }

}
2
Marlo Quidato

@richardjsimkinsが述べたように、これは少なくともいくつかのケースでは制約に関係しているようです。私の場合、起動画面の中央に画像を追加したかったのは、この場合、プログラムでtintColorを設定できないためです。純粋なストーリーボードソリューションを見つけなければなりませんでした。

制約を使用して画像ビューを中央に配置するときに、tintColorが設定されていないことがわかりました。つまり、安全な領域で水平/垂直に中央に配置します。

代わりに、安全な領域の先頭/末尾/上部/下部に制約付きのスタックビューを追加し、整列中心、分布塗りつぶしを持つ安全な領域に画像ビューを埋め込みました。これは、imageViewを安全な領域の中央に直接配置するのと同じ位置に解決され、tintColorが有効になりました。

スタックビューを使用してtintColorを強制的に機能させることに解決する必要はありませんが、バグに対する小さくてかなりきれいな回避策だと思います。

1
Darumar

ストーリーボードのデフォルトの色合いを維持 enter image description here

選択した色でユーザー定義のランタイム属性を追加します enter image description here

ストーリーボードにはデフォルトの色合いで画像が表示されますが、実行すると選択した色が表示されます。

0

XCode 10.3でこの問題が発生しました。これは、アセットに追加する前にストーリーボードに画像を追加することに関連していると思われるXCodeのバグです。

私が助けたのは、色合いをランダムな色に変更してから、デフォルトに戻すことです。

その結果、XCodeは<color key="tintColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>をストーリーボードXMLに追加しましたが、これは以前は欠落していました。 colorSpace="custom"として追加されていますが、XCodeビルダーはdefaultとして表示します。

0
Gene S