LoginSignup
14
13

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-02-24

Screen Shot 0029-02-24 at 21.08.31.png
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"のチェックを外すというものでした。
Screen Shot 0029-02-24 at 22.13.01.png

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

本当はこの対処法は良くないのかもしれない?

やはりお前らのiOS7対応は間違っている(解説編)では上記の対処法によって起きる問題点や認識の間違いが説明されています。

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

試した対処法

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

PageViewController.swift
override func viewDidLoad() {
    automaticallyAdjustsScrollViewInsets = false
}
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

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

AppDelegate.swift
let rootVC = PageViewController()
let navigationController = UINavigationController(rootViewController: rootVC)
self.window?.rootViewController = navigationController

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

上記の調整が必要なかったケース

PageViewController(コード) + TableViewで、NavigationBarをコードでセットした時

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

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

まとめ

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

14
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13