UINavigationController -> UIPageViewController -> UIViewController -> UITableView
という構成で実装をしていた時に、TableViewがNavigationBarのしたに潜りこんでしまったので対処法を調べてみました。
環境:
Xcode 8.2.1
Swift 3
iOS 10.2.1
##iOS7から起こるようになった?
これはiOS7から起きているようで、多くの人が対処に困った問題のように見受けられました。
UINavigationControllerと領域拡張に潜む罠
[Objective-C] UIScrollView/UITableViewのcontentOffsetがずれるときがある
Why content insets of a UITableView inside a UIPageViewController get messy right after an interaction?
最初から潜り込んでいる場合や、
タップやスクロールをすると潜り込んでしまう場合などがあるようです。
##ググるとよく出てきた対処法
ググった時に対処法としてよく出てくるのは
コードであれば
self.edgesForExtendedLayout = UIRectEdgeNone
Storyboardであれば
Extend Edgesの"Under Top Bars"と"Under Bottom Bars"のチェックを外すというものでした。
私も最初にこの方法を試し、TableViewがNavigationBarに潜りこむという問題は解決されました。
##本当はこの対処法は良くないのかもしれない?
やはりお前らのiOS7対応は間違っている(解説編)では上記の対処法によって起きる問題点や認識の間違いが説明されています。
基本的にExtend Edgesの項目は触らないで(チェックしたままで)実装するのが良いようです。
##試した対処法
PageViewControllerのautomaticallyAdjustsScrollViewInsetsをfalseにし、
TableViewのcontentInsetとscrollIndicatorInsetsを調整すると潜り込まなくなりました。
override func viewDidLoad() {
automaticallyAdjustsScrollViewInsets = false
}
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
let storyboard = UIStoryboard(name: "PageViewController", bundle: nil)
let rootVC = storyboard.instantiateViewController(withIdentifier: "PageViewController")
let navigationController = UINavigationController(rootViewController: rootVC)
self.window?.rootViewController = navigationController
####PageViewController(コード) + TableView
let rootVC = PageViewController()
let navigationController = UINavigationController(rootViewController: rootVC)
self.window?.rootViewController = navigationController
PageViewControllerをstoryboardで作成した場合も、コードで作成した場合もTableViewがNavigationBarに潜りこむ問題が発生しました。
###上記の調整が必要なかったケース
####PageViewController(コード) + TableViewで、NavigationBarをコードでセットした時
let rootVC = PageViewController()
let navigationController = UINavigationController(rootViewController: rootVC)
navigationController.navigationBar.UIColor.black //navigationBarに変更を加える
self.window?.rootViewController = navigationController
NavigationControllerのnavigationBarをコードで変更した場合のみ、調整の必要がなく正常に動作しました。
*この場合tableViewのcontentInsetなどを調整しているとおかしくなる
##まとめ
今回なぜこのような差異があるのかというところまでは時間がなく調べられなかったのですが、
先ほど紹介したUINavigationControllerと領域拡張に潜む罠で説明されているcontentInsetsの付与の有無、タイミングによって違いが出てきているようです。