前置き
大規模の新規アプリを作っていて、デザイナーとやりとりするところで、うまくImageViewでの画像表示について伝えることができませんでした。これまで動的に変化する画像サイズを扱ったことがなく、曖昧に理解したままやっていたので、中身についてちゃんと理解しようと思った。
環境
- swift 4.0
- Xcode 9.2
(本題) ImageViewのContetModeを理解する
高さ 200px, 幅 200pxのImageViewを画面の中心に置いた状態でContentModeによってどのように画像の表示が変わるのかを見ていきます。
ちなみにContent Modeはstoryboard上ではImageViewを選択したときのInspectorで設定できます。
コードでは次のように設定できます。
var imageView = UIImageView()
imageView.contentMode = .scaleToFill
使用する画像は横:100、縦:75の大きさです。
それでは、各描画形式について説明します。
scaleToFit
- ImageViewのデフォルトのContent Mode
- 画像の比率をImageViewの比率に合わせる
- 画像サイズの比率が変わるのであまり使ってほしくない
今回のImageViewの比率は1:1ですが、画像は4:3です。
ImageViewの比率に合わせるため画像の比率が1:1になります。そのため、縦が4/3倍長くなります。
AspectFit
- ImageViewのサイズ内で画像の比率そのままで表示
- 画像の比率とImageViewの比率が違っていたら、ImageViewに画像が表示されない空白ができる。
- 画像の中心とImageViewの中心は同じになる
個人的によく使うのがAspectFit。ImageViewのサイズ内で、画像を元の比率のまま表示する。今回のようにImageViewが1:1で画像が4:3の場合、1/4高さがあまるので、1/8ずつ上下に空白(↑画像では灰色の部分)が出来る。
AspectFill
- ImageViewのサイズ比率そのままで、ImageViewに空白ができないように表示する。
- ImageViewと画像の比率が違う場合、ImageViewをはみ出す
- 画像の中心とImageViewの中心は同じになる
仕事でやっててこれがうまく説明できなかった。。。
画像比率そのままで、ImageViewに空白ができないように表示したい場合に、使用する。
具体的には次のような式で求められます
ImageView -> Width: Heihgt = Wa: Ha
画像 -> Width: Heihgt = Wb: Hb
Wa/Ha < Wb/Hb -> 画像が (Wb/Hb - Wa/Ha)/2ずつ ImageView左右にはみ出る
Wa/Ha > Wb/Hb -> 画像が (Wa/Ha - Wb/Hb)/2ずつ ImageView上下にはみ出る
Redraw
- 基本的にはScaleToFillと同じ
- ScaleToFillとの違いは、ScaleToFillがImageViewのdrawRectのところで1度呼ばれると後からは変更が聞かないのに対し、Redrawでは、drawRectが呼ばれるたびにImageViewのサイズに追従します。
今まで一度も使ったことないですが、上に書いたとおり、ImageViewのdrawRectが何回か呼ばれてそのサイズに画像を合わせたい場合に使うのが良さそうです。
その他(Center,Top,Left,Right...)
- 画像サイズそのままで、ImageViewに対する位置を指定する。
- つまり画像サイズは変わらない
(Centerに指定した場合)
画像の元サイズに気をつけて設定しましょう。
終わりに
参考になりましたらいいねお願いします!!