iOSアプリ開発でNavigationBarを使っていると、ViewがNavigationBarの下に潜り込んでしまうことがあります。
今回はその解決策を備忘録的にいくつか書きます。
解決策1
この現象をググるとよく出て来る方法で、これがあります。
edgesForExtendedLayout = []
edgesForExtendedLayout
に対して[]
を指定することによってViewの上端の位置(開始位置)をNavigationBarの下端にできるので、NavigationBarと重ならないようになります。
ですが副作用として、Viewが開始位置がずれたことによって、NavigationBarの背面がデフォルトの背景になるため真っ黒になります。そのため、NavigationBarが半透明になっているとNavigationBar全体が真っ黒になってしまいます。
In iOS 10 and earlier, use this property to report which edges of your view controller extend underneath navigation bars or other system-provided views. The default value of this property is all, and it is recommended that you do not change that value.
If you remove an edge value from this property, the system does not lay out your content underneath other bars on that same edge. In addition, the system provides a default background so that translucent bars have an appropriate appearance. The window’s root view controller does not react to this property.
Source: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621515-edgesforextendedlayout
解決策2
次は、NavigationBarのisTranslucent
で不透明にして、extendedLayoutIncludesOpaqueBars
をfalse
にする方法です。
navigationController?.navigationBar.isTranslucent = false
extendedLayoutIncludesOpaqueBars = false // default
NavigationBarを不透明にする、そして不透明のときはextendedLayoutを適用させないようにすれば、NavigationBar下に潜り込まないようになります。
ちなみに
extendedLayoutIncludesOpaqueBarsはデフォルトでfalse
になっています。
解決策3
もしTableViewなどのUIScrollViewを継承しているコンポーネントを使うのであれば、extendedLayoutIncludesOpaqueBars
をtrue
にして、contentInsetAdjustmentBehavior
で調整してもらうことで潜り込まないようにもできます。
extendedLayoutIncludesOpaqueBars = true
edgesForExtendedLayout = .all // default (.topでも可)
ちなみに
edgesForExtendedLayoutはデフォルトで.all
contentInsetAdjustmentBehaviorは.automatic
になっています。
最後に
実験用のサンプルを作ったので、もっと詳しく挙動を知りたい方は試して見てください!
https://github.com/0eta0/OverlapNavBarTest
参考
https://medium.com/@wailord/extended-layout-in-ios-pre-ios-11-5eff2debf28
https://medium.com/@wailord/the-particulars-of-the-safe-area-and-contentinsetadjustmentbehavior-in-ios-11-9b842018eeaa