Xcode の Playground で画像を表示して contentMode の違いを学ぼう

Xcode の Playground では、以下の設定でアシスタントエディタに画像を表示することができます。

import PlaygroundSupport

// 非同期処理を許可
PlaygroundPage.current.needsIndefiniteExecution = true

// アシスタントエディタにビューを表示
PlaygroundPage.current.liveView = view

これを利用して、UIImageView の contentMode による画像表示の違いを見ていきます。サイズが 200 x 200 の UIImageView を用意して、それを 300 x 300 の UIView の上に載せます。表示の違いが良くわかるように UIView の背景色は黒、UIImageView の背景色は青にします。

※ 動作確認は Xcode9 で行っています
import UIKit
import PlaygroundSupport

let view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
imageView.image = UIImage(named: "sample.png")
imageView.center = view.center
imageView.backgroundColor = .blue
view.addSubview(imageView)

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = view

画像は Resources に追加します。今回使用する画像のサイズは 300 x 212 です。

Scale to Fill

contentMode のデフォルト値です。画像の縦横比を無視して、画像を UIImaveView のサイズに合わせて伸縮させて表示します。上記のソースは Scale to Fill で表示され、アシスタントエディタでは以下のように表示されます。

Aspect Fit

縦横の比率を維持して 長い方を基準にして UIImageView のサイズ内に収めます。

imageView.contentMode = .scaleAspectFit

一番きれいに表示できますが、UIImageView の縦横比と元画像の縦横比が違うと空白が発生します(上の画像の青い部分です)。

Aspect Fill

縦横の比率を維持し、短い方を基準にして画像全体を表示します。

imageView.contentMode = .scaleAspectFill

縦横の比率を維持しながら全部の画像領域を表示するので、場合によって UIImageView のサイズよりも大きくなることがあり、その場合画像は UIImageView からはみ出す形で表示されます。はみ出た部分を切り取って表示するには、clipsToBounds を true に設定します。

imageView.clipsToBounds = true

すると、以下のように UIImageViewのサイズ(200 x 200)をはみ出た部分は表示されなくなります。

top / bottom / left / right / topLeft / topRight / bottomLeft / bottomRight

縦横の比率を維持しながら、どの部分を基準に表示するかを指定します。Aspect Fill と同じように全部の画像領域を表示するためにはみ出してしまうので、clipsToBounds を true に設定します。ここでは right と left を指定した例を紹介します。

imageView.contentMode = .right
imageView.clipsToBounds = true

右側を基準として表示され、はみ出した左側は切り取られます。

imageView.contentMode = .left
imageView.clipsToBounds = true

左側を基準として表示され、はみ出した右側は切り取られます。