Swift・iOS

Swiftを中心に学んだことを記録に残すブログです。技術に関係ない記事もたまに書いています。

【Swift】UIImageView/どの画面サイズでも画像の縦横比を保ったまま全領域を表示させたい(バナー画像のレイアウト)

「どの画面サイズでもバナー画像が切れることなく、縦横比も保ったままレイアウトする方法ってどうすれば良いんだっけ?」とレイアウトわかってない感満載な現象が起こったので、記事に残しておきます。

 

■開発環境

Xcode 10.2

・Swift 5.0

 

■やりたいこと

以下のように画面上部にバナー画像を配置し、どの端末でも画像が切れることなく縦横比も保ったまま表示させたい。

f:id:hfoasi8fje3:20190501223635p:plain


■詰まったこと

前提として、バナーは以下のようにレイアウトしました。 

f:id:hfoasi8fje3:20190501224817p:plain

 

バナー画像を配置してみます。

Content ModeをScale To Fillにするとアスペクト比を無視して画像全体を表示するため、以下画像だと横に伸びて表示されます。

※画像はサンプルで、以下サイトの画像を使用しています。

https://pixabay.com/ja/

f:id:hfoasi8fje3:20190501224322p:plain

 

Content ModeがAspect Fitの場合は画像のアスペクト比を保ったままUIImageViewに表示するため、今度は横に余白ができます。

f:id:hfoasi8fje3:20190501225221p:plain

 

Content ModeをAspect Fill(Clip to Boundsの設定含む)にすると、スペースを空けずに表示されるのはよいものの、今回の場合は画像上部と下部がカットされて表示されてしまいます。また、端末の画面サイズによって画像の表示領域が変わってしまいます。

f:id:hfoasi8fje3:20190501225441p:plain

 

あれ・・・?どうレイアウトすればよいんだっけ・・・?

 

■結論

サイズ(幅、高さ)が設定されたUIImageViewに対して画像を当てこまない。

画像のアスペクト比(縦横比)とUIImageViewのアスペクト比を合わせる。

 

■「サイズ(幅、高さ)が設定されたUIImageViewに対して画像を当てこまない」とは

今回、UIImageViewに高さを設定してレイアウトしていました。(「詰まったこと」の1枚目の画像がレイアウト設定の詳細です)

f:id:hfoasi8fje3:20190501230717p:plain

そうすると、画像をUIImageViewの高さに合わせて収縮することで対応することになります。そのため、画面サイズが変わっても画像の全領域を縦横比を保ったまま表示することは難しくなってしまいます。


■画像のアスペクト比(縦横比)とUIImageViewのアスペクト比を合わせる方法

高さを設定するのではなく、Aspect Ratioを設定することで対応します。

 

※手順

まずは、高さを削除します。

f:id:hfoasi8fje3:20190501232741p:plain

 

Aspect Ratoの制約を追加します。

f:id:hfoasi8fje3:20190501233219p:plain

 

画像のアスペクト比(縦横比)とUIImageViewのアスペクト比を合わせていきます。

今回使用しているサンプル画像のサイズは960×639でした。縦横比は320:213になるので、UIImageViewにも同じ縦横比を設定します。

アスペクト比に関する制約を選択してください。

f:id:hfoasi8fje3:20190501233820p:plain

 

Multiplierに画像のアスペクト比である320:213を設定すると、どの画面サイズでも画像の全領域が表示されるようになります。

f:id:hfoasi8fje3:20190501234017p:plain

 

サンプル画像の縦横比の問題で当初やりたかったようなバナー画像よりも高さが出てしまっていますが、実際はバナー画像を横:縦=5:1で作成して、UIImageView側も同じアスペクト比で設定するとやりたかったことに近い表示になります。 

 

■参考リンク

https://developer.apple.com/documentation/appkit/nswindow/1419507-aspectratio

https://qiita.com/Saayaman/items/a23519ff5a8ad287cf20

https://dev.classmethod.jp/smartphone/iphone/autolayout-aspect-ratio/