TableViewがNavigationBarに潜りこんだ時の対処法

![Screen Shot 0029-02-24 at 21.08.31.png](https://qiita-image-store.s3.amazonaws.com/0/97191/df6bc693-23bc-ba70-50fa-866aa6a6a0e6.png)
UINavigationController -> UIPageViewController -> UIViewController -> UITableView
という構成で実装をしていた時に、TableViewがNavigationBarのしたに潜りこんでしまったので対処法を調べてみました。

環境:
Xcode 8.2.1
Swift 3
iOS 10.2.1


##iOS7から起こるようになった？
これはiOS7から起きているようで、多くの人が対処に困った問題のように見受けられました。
[UINavigationControllerと領域拡張に潜む罠](http://qiita.com/glayash/items/b759bd1da0aedf8adc82)
[[Objective-C] UIScrollView／UITableViewのcontentOffsetがずれるときがある](http://qiita.com/edo_m18/items/0608f07e49cee5a9c52e)
[Why content insets of a UITableView inside a UIPageViewController get messy right after an interaction?](http://stackoverflow.com/questions/25728283/why-content-insets-of-a-uitableview-inside-a-uipageviewcontroller-get-messy-righ)


最初から潜り込んでいる場合や、
タップやスクロールをすると潜り込んでしまう場合などがあるようです。

##ググるとよく出てきた対処法
ググった時に対処法としてよく出てくるのは
コードであれば
`self.edgesForExtendedLayout = UIRectEdgeNone`

Storyboardであれば
Extend Edgesの"Under Top Bars"と"Under Bottom Bars"のチェックを外すというものでした。
![Screen Shot 0029-02-24 at 22.13.01.png](https://qiita-image-store.s3.amazonaws.com/0/97191/82cc5ba8-8934-27e0-c0d7-a48e2c490be1.png)


私も最初にこの方法を試し、TableViewがNavigationBarに潜りこむという問題は解決されました。

##本当はこの対処法は良くないのかもしれない？
[やはりお前らのiOS7対応は間違っている(解説編)](http://qiita.com/yimajo/items/254c7cebab7864678246)では上記の対処法によって起きる問題点や認識の間違いが説明されています。

基本的にExtend Edgesの項目は触らないで(チェックしたままで)実装するのが良いようです。


##試した対処法
PageViewControllerのautomaticallyAdjustsScrollViewInsetsをfalseにし、
TableViewのcontentInsetとscrollIndicatorInsetsを調整すると潜り込まなくなりました。

```swift:PageViewController.swift
override func viewDidLoad() {
    automaticallyAdjustsScrollViewInsets = false
}
```


```swift:ViewController.swift
override func viewDidLoad() {
    let edgeInsets = UIEdgeInsets(top: 64, left: 0, bottom: 0, right: 0)
    tableView.contentInset = edgeInsets
    tableView.scrollIndicatorInsets = edgeInsets
}
```

UIEdgeInsetsのtop:64ptはステータスバーとNavigationBarの高さの合計です。


##実装方法によって挙動に差異がある？
このNavigationBarにTableViewが潜り込んでしまう問題は、
NavigationBarをコードでセットしているかによって差異がありました。

###上記の調整が必要だったケース
####PageViewController(storyboard) + TableView
```swift:AppDelegate.swift
let storyboard = UIStoryboard(name: "PageViewController", bundle: nil)
let rootVC = storyboard.instantiateViewController(withIdentifier: "PageViewController")
let navigationController = UINavigationController(rootViewController: rootVC)
self.window?.rootViewController = navigationController
```

####PageViewController(コード) + TableView
```swift:AppDelegate.swift
let rootVC = PageViewController()
let navigationController = UINavigationController(rootViewController: rootVC)
self.window?.rootViewController = navigationController
```

PageViewControllerをstoryboardで作成した場合も、コードで作成した場合もTableViewがNavigationBarに潜りこむ問題が発生しました。

###上記の調整が必要なかったケース
####PageViewController(コード) + TableViewで、NavigationBarをコードでセットした時

```swift:AppDelegate.swift
let rootVC = PageViewController()
let navigationController = UINavigationController(rootViewController: rootVC)
navigationController.navigationBar.UIColor.black //navigationBarに変更を加える
self.window?.rootViewController = navigationController
```

NavigationControllerのnavigationBarをコードで変更した場合のみ、調整の必要がなく正常に動作しました。
*この場合tableViewのcontentInsetなどを調整しているとおかしくなる


##まとめ
今回なぜこのような差異があるのかというところまでは時間がなく調べられなかったのですが、
先ほど紹介した[UINavigationControllerと領域拡張に潜む罠](http://qiita.com/glayash/items/b759bd1da0aedf8adc82)で説明されているcontentInsetsの付与の有無、タイミングによって違いが出てきているようです。