以下の場合、同じ設定と同じテンプレート画像を持つ2つのUIImageViewがあります...しかし、1つは画像に色を付け、もう1つはしません
動作中のUIImageView
を複製し、他の代わりに配置して動作しました。これは私に何度も起こり、この解決策は常に機能しましたが、私はまだ何が間違っていたのだろうかと思いますか? Xcodeのバグになりますか?同様のことがあなたに起こりましたか? Xcode 8.1を使用しています。
サブクラスや別のIBInspectable
属性を必要としない最適なソリューション:
import UIKit
extension UIImageView {
override open func awakeFromNib() {
super.awakeFromNib()
tintColorDidChange()
}
}
問題は、null状態のない色合いの値に起因します(Storyboard/Interface Builder UI内)。 XcodeがUIImageView
に色合いを適用するかどうかを決定するために、追加のテストがあるようです。 Xcodeでは、明らかにこれはUIImageView
に適用される制約を評価することで行われます。私の知る限り、このテストは文書化されていません。
UIImageView
の2つ(または1つ)の側面に「最近傍への間隔」制約のみがある場合、UIImage.renderingMode
に設定された値に関係なく色合いは適用されません。
UIImageView
の3つ(またはすべて)の側面に「最近傍への間隔」制約がある場合、UIImage.renderingMode
が.alwaysTemplate
に設定されている場合、色合いが適用されます。
ストーリーボード/インターフェースビルダーのみのアプローチでは、画像をUIImage.renderingMode
に設定し、画像をアセットカタログに追加してから、画像セットの[レンダリング]プロパティを[テンプレート画像]に変更します。
プログラムでtintColor
を設定してみてください。それは私のために問題を修正しました。
UIImageViewにバグがあると思います。ストーリーボードで色合いを設定すると、アセットがテンプレートとしてレンダリングするように設定されていても、その色合いは適用されません。
回避策は、ストーリーボードのUIImageViewの親ビューに色合いを適用することです。
または、tintColorをnilに設定し、UIImageViewをアウトレットにバインドしてコードを再度戻します。
この拡張機能を使用して、インターフェイスビルダーからUIImageView tintColorを設定します。
extension UIImageView {
@IBInspectable var imageColor: UIColor! {
set {
super.tintColor = newValue
}
get {
return super.tintColor
}
}
}
既存のUIImageViewを削除して新しいUIImageViewを追加すると、問題はなくなりました。どうやら、状況は、画像をAssetsフォルダーに追加した後にUIImageViewを追加する必要があるということです。
ランタイム属性のトリックはうまくいきませんでした。私はこの種のものを修正するためだけにこのクラスを作成しました。問題のあるすべての画像ビューをこのクラスに設定するだけです。
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
}
}
@richardjsimkinsが述べたように、これは少なくともいくつかのケースでは制約に関係しているようです。私の場合、起動画面の中央に画像を追加したかったのは、この場合、プログラムでtintColorを設定できないためです。純粋なストーリーボードソリューションを見つけなければなりませんでした。
制約を使用して画像ビューを中央に配置するときに、tintColorが設定されていないことがわかりました。つまり、安全な領域で水平/垂直に中央に配置します。
代わりに、安全な領域の先頭/末尾/上部/下部に制約付きのスタックビューを追加し、整列中心、分布塗りつぶしを持つ安全な領域に画像ビューを埋め込みました。これは、imageViewを安全な領域の中央に直接配置するのと同じ位置に解決され、tintColorが有効になりました。
スタックビューを使用してtintColorを強制的に機能させることに解決する必要はありませんが、バグに対する小さくてかなりきれいな回避策だと思います。
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
として表示します。