Viewを高さ指定で上端に配置しSafe Areaの外側も同じ色にする


はじめに

独自のナビゲーションバーを実装しているアプリで以下の条件でiPhoneX対応していました。

  • iPhoneXとその他でNavigationBarのStatusBarを除いた高さは同じにしたい
  • StatusBarとNavigationBarは同じ色にしたいが背景色のためだけに追加のViewは置きたくない
  • コードによって端末やバージョン判定、StatusBarの高さの取得などはできるだけしたくない

指定した高さのViewをSafe Areaの上端に配置すると外側まで色が変わってくれるのが理想です。

UIToolBarは、Safe Areaぴったりに配置するとSafe Areaの下まで背景色がついてくれます。

(左:Safe Areaから1だけ上にずれてる状態 右:Safe Areaにぴったり)

しかし、ただのUIViewは空気を読んでくれませんでした。


(A. Safe AreaのTopに高さ44のViewを配置)


(B. SuperViewのTopに高さ44のViewを配置)

Safe Areaからの高さを設定する場合にはStatusBarの背景色をどう描画するかを解決する必要があります。
SuperViewからの高さを設定する場合にはStatusBarの高さの違いによるViewの高さの違いを解決する必要があります。

Safe AreaのTopからの高さを指定しつつ、SuperViewからSafe Areaまでの間も描画できれば目標が果たせそうです。

解決策

設置したいViewの高さをxとして、ViewのTopをSuperView.Top、BottomをSafe Area.Top - xに設定することで実現します。
以下に手順を説明します。

1. ViewをSuperView.TopとSafe Area.Bottomの間に設置する

  • LeftとRightはSafe Areaに対して0に設定する
  • TopはSuperViewに対して0に設定する(Safe Areaになっていないか確認)
  • BottomはSafe Areaに対して0に設定する(ここで設定されるのはSafe Area.Bottom)

2. BottomをSafe Area.BottomからSafe Area.Topに変更する

  • BottomからTopに変更することで、ViewがSafe Areaより上側だけに描画される

3. Safe Area.TopからのConstantを0からViewの高さに変更する

  • 上端に設置したいViewの高さを指定する(マイナスにすることに注意)

4. 完成

環境

  • Xcode 9.0
  • iOS 11.0

サンプル

この方法を利用した擬似NavigationBarと、それを下端に応用した擬似ToolBarのサンプルです。
https://github.com/ninten320/PseudoNavigationAndToolBar