iOS 11&iPhone X上のUIscrollView(UItableView)コンテンツオフセットの問題

4916 ワード

の原因となる
  • iOS 11のUIViewControllerautomaticallyAdjustsScrollViewInsets属性はもう使用されていません.UIScrollViewcontentInsetAdjustmentBehavior属性を使用して代替する必要があります.UIScrollViewframeが安全領域の範囲を超えた場合、システムはUIScrollViewsafeAreaInsets値を自動的に調整し、UIScrollViewadjustContentInset値に影響を与え、UIScrollViewの内容がずれる.iOS 11がUIScrollViewのコンテンツオフセット量を制御する属性はadjustContentInsetであり、adjustContentInsetの値はシステムがsafeAreaInsetscontentInsetに基づいて計算したものであり、計算方式はcontentInsetAdjustmentBehaviorによって決定される.
  • 補足:ナビゲーションバーがある場合safeAreaInsets値は自動的に(88,0,34,0)に調整されます.ナビゲーションバーがない場合のsafeAreaInsetsの値は(44,0,34,0)です.

  • 安全区域
  • セキュリティエリアはiOS 11が新たに提案したものです.
  • セキュリティ領域は、viewを画面全体の可視部分に配置するのに役立ちます.navigationBarを透明に設定しても、システムは、navigationBarbottomから安全領域が始まり、システムのステータスバーやナビゲーションバーに覆われないことを保証していると考えている.controllerは、additionalSafeAreaInsetsを使用して、インタフェース上にカスタムcontentを含むようにセキュリティ領域を拡張することができる.各viewは、セキュリティ領域埋め込みの大きさを変更することができ、controllerも可能である.
  • safeAreaInsetsの属性は、viewからviewまでの安全領域の余白を反映する.UIViewControllerのルートビューの場合、safeAreaInsetsの値は、statusbarおよび他の視覚的barsによって覆われた領域、およびadditionalSafeAreaInsetsによってカスタマイズされた他のinsetsの値を含む.view階層の他のviewsafeAreaInsets値は、viewが上書きされた部分を反映している.viewがすべて親ビューのセキュリティ領域内にある場合、safeAreaInsetsの値は(0,0,0,0)です.

  • adjustContentInsetプロパティの計算方法
    まず、iOS 11に追加されたUIScrollViewの2つのプロパティ:adjustContentInsetcontentInsetAdjustmentBehaviorを参照してください.
  • UIScrollViewContentInsetAdjustmentAutomatic:scrollViewautomaticallyAdjustsScrollViewContentInset = YESUIViewControllerにあり、このUIViewControllerUINavigationControllerに含まれている場合、スクロールの有無にかかわらずtop & bottomに設定されます.その他の場合はadjustedContentInset = safeAreaInset + contentInsetと同じです.
  • UIScrollViewContentInsetAdjustmentScrollableAxes:スクロール可能な方向にUIScrollViewContentInsetAdjustmentScrollableAxes、スクロール不可能な方向にadjustedContentInset = safeAreaInset + contentInset;adjustedContentInset = contentInsetおよびscrollEnabledalwaysBounceHorizontal / Vertical = YESに依存するデフォルトはscrollEnabledであるため、多くの場合、計算方法はYes
  • である.
  • adjustedContentInset = safeAreaInset + contentInset : UIScrollViewContentInsetAdjustmentNever .adjustedContentInset = contentInsetcontentInsetAdjustmentBehaviorに設定されている場合、UIScrollViewContentInsetAdjustmentNeverの値はadjustContentInsetの値の影響を受けない.
  • safeAreaInset : UIScrollViewContentInsetAdjustmentAlways

  • 解決策
  • は、adjustedContentInset = safeAreaInset + contentInsettableView値を再設定し、contentInset値を相殺する.
  • safeAreaInsetに設定されたadjustedContentInset = contentInset + safeAreaInsetの属性はtableViewであり、contentInsetAdjustmentBehaviorである.
  •     //  API:`@available(iOS 11.0, *)`          
        if ( @available(iOS 11.0, *) ) {
            self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        }
    
  • iOS 11 UIScrollViewContentInsetAdjustmentNever新規属性adjustedContentInset = contentInsetを設定します.iOS 11以前は、UIViewControlleraddtionalSafeAreaInset属性をNOに設定することで、UIViewControllerautomaticallyAdjustsScrollViewInsetsをシステム調整することを禁止していました.tableViewのレベルから問題を解決するには、contentInsetcontrollerの属性を設定することによって、controlleradditionalSafeAreaInsetsがセキュリティ領域の範囲を超えていない場合、システムはtableViewframeの値を調整せず、コンテンツオフセットも発生しないため、問題を解決することができる.

  • グループヘッダグループテール高さ
  • tableViewのタイプがsafeAreaInsetである場合、システムのデフォルトのtableViewのヘッダとヘッダはピッチがあり、このピッチが必要でない場合、iOS 11は、エージェントメソッドUITableViewStyleGroupedを実装することによって(より小さな値:0.01を返す)前に解決することができる.
  • iOS 11以降は、プロキシメソッドtableViewだけでなく、プロキシメソッドheightForHeaderInSection / heightForFooterInSectionを実装してこそ、間隔を取り除くことができる.あるいは以下のコードを追加して高さ推定を閉じても問題は解決できます.
  • self.tableView.estimatedRowHeight = 0;
    self.tableView.estimatedSectionHeaderHeight = 0;
    self.tableView.estimatedSectionFooterHeight = 0;