LoginSignup
6
7

More than 5 years have passed since last update.

[ios]iPhone Xでも、TableViewのheaderを画面上に残らないようにする

Last updated at Posted at 2017-12-22

TableViewのヘッダーはスクロールしても画面内に止まるようになっています。
それを無理やり画面に残らないようにする方法は下記の地道な方法があります。
セクションヘッダが画面上に残らないようにする方法

safeAreaを考慮しない場合
private let sectionHeaderHeight: CGFloat = 8
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    /// sectionHeaderが上部に残らないようにする
    let offsetY = scrollView.contentOffset.y

    if offsetY <= sectionHeaderHeight && offsetY >= 0 {
        scrollView.contentInset = UIEdgeInsets(top: -offsetY, left: 0, bottom: 0, right: 0)
    } else if offsetY >= sectionHeaderHeight {
        scrollView.contentInset = UIEdgeInsets(top: -sectionHeaderHeight, left: 0, bottom: 0, right: 0)
    }
}

しかし、これだとiPhone Xの場合にsafeArea上で思った通りに動きません。

before2.gif

tableViewにはios11から safeAreaInsets というものが追加されおり、この safeAreaInsetscontentsInsets を合算した adjustedContentInset を使ってヘッダー位置の調整を行なっています。
よって、上記サンプルのcontentOffsetにsafeAreaの概念を入れてあげます。

safeAreaを考慮したサンプル
private let sectionHeaderHeight: CGFloat = 8
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    /// sectionHeaderが上部に残らないようにする
    let offsetY = scrollView.contentOffset.y

    let safeAreaInset: CGFloat
    if #available(iOS 11.0, *) {
        safeAreaInset = scrollView.safeAreaInsets.top
    } else {
        safeAreaInset = 0
    }

    let top: CGFloat
    if offsetY > sectionHeaderHeight{
        /// 一番上のheaderの最下部が画面外へ出ている状態
        top = -(safeAreaInset + sectionHeaderHeight)
    } else if offsetY < -safeAreaInset {
        /// 初期状態からメニューを下に引っ張っている状態
        top = 0
    } else {
        /// safeArea内を一番上のheaderが移動している状態
        top = -(safeAreaInset + offsetY)
    }
    scrollView.contentInset = UIEdgeInsets(top: top, left: 0, bottom: 0, right: 0)
}

after.gif

6
7
0

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
6
7