UIImageView
を使用して、いくつかのサムネイル画像を固定サイズ(100x100)で描画しようとしています。イメージビューのフレームサイズを100x100に設定し、contentMode
をUIViewContentModeScaleAspectFill
に設定しました。
私の理解では、これにより画像は設定したサイズで描画され、画像は画像の領域を塗りつぶし、画像ビューに設定したサイズ外の画像の部分をクリップします。ただし、画像は、設定した100x100サイズよりも大きくまたは小さく描画されます。
contentMode
をUIviewContentModeScaleToFill
に設定すると、画像は正確に100x100で描画されますが、それらの寸法に収まるように歪んでいます。アスペクトフィルが期待どおりにクリッピングされない理由はありますか?
私のコードは次のとおりです。
_photoView = [[UIImageView alloc] initWithImage:photoImage];
_photoView.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:_photoView];
CGRect photoFrame = _photoView.frame;
photoFrame.size = CGSizeMake(100, 100);
_photoView.frame = photoFrame;
よりよく説明するために、ここに私が見ているもののスクリーンショットがあります。緑の四角は、UIView
を含むUIImageView
を含んでいます。背景色を緑に設定し、ビューのフレームを100x100に設定しました。テストとして、UIImageViews
のサイズは50x50です。ご覧のとおり、...AspectFill
を使用すると、画像のサイズは50x50にならず、場合によっては希望の位置からオフセットされます。 ...ScaleToFill
を使用すると、サイズは正しくなりますが、画像がゆがみます。
知識を広げたい場合は、 iOS UIViewスタックのレンダリング の方法に関する非常に良い記事があります。 描画パイプライン全体 についてのより詳細な記事もあります。
要約すれば:
Rasterisation-ビューのコンテンツはすべて、ビューの境界の座標空間でラスタライズ(描画またはオフスクリーンピクセルバッファ)されます。これは、画像データまたはカスタム描画(つまり、drawRect:
)ですが、サブビューコンテンツです。このラスタライズでは、contentMode
プロパティが考慮されます。
ビューの境界外にあるものはすべて破棄されます。
Composition-結果は、サブビューからスーパービューに合成されます(互いの上に描画されます)。これは、サブビューのフレームプロパティを使用します。
スーパービューでclipsToBounds
プロパティがYES
の場合、境界外のsubviewコンテンツは破棄されます。
同じ問題があり、「クリップサブビュー」にチェックを入れることで解決しました。
画像は、ストーリーボードプレビューのすべてのビュー(3.5、4、4.7、5.5、ipad)で正しく表示されていましたが、シミュレーターでは表示されていませんでした。
「クリップサブビュー」にチェックを入れた後、問題は解決しました。 :)
すべてが失敗した場合、
viewDidLayoutSubviewsメソッドで境界にクリップを行います。
例:
override func viewDidLayoutSubviews() {
imageProfile.layer.cornerRadius = imageProfile.bounds.size.width/2
imageProfile.clipsToBounds = true
imageProfile.layer.masksToBounds = true
}
私のサブビューのサイズは変更されていましたが、それはxibに自動レイアウトが設定されているためだとわかりました。