post Image
AutoLayoutでiPhoneXのedge-to-edge対応

iPhoneXが新しく登場しましたが、従来の実装ではちゃんと全画面表示にならなかったり、逆にiPhoneXのSafeAreaからはみ出してしまう画面が出てくると思います。
その例と修正方法をいくつかまとめたいと思います。

deprecatedになった topLayoutGuidebottomLayoutGuide

topLayoutGuidebottomLayoutGuide がdeprecatedになってしまいましたが、Xcode9では safeAreaLayoutGuide に制約を貼ることになります。
では今まで topLayoutGuidebottomLayoutGuideに貼っていた制約はXcode9でどうなるのかというと


Xcode8でつけた制約がそのまま貼られています。

そしてそれをiPhoneXで起動するとどうなるのか?

こうなります。
テーブルビューのコンテンツが下まで表示されず、SafeAreaで切られた見た目になっています。

これをbottomをsuperViewに対して貼るように修正するとちゃんと下までスクロールするようになります。

ちなみにHuman Interface Guidelineに以下のように書いてありますが、テーブルビューを使う場合、UITableViewControllerを使えば勝手に全画面表示表示になってくれるので自分で意識する必要はありません。

Most apps that use standard, system-provided UI elements like navigation bars, tables, and collections automatically adapt to the device’s new form factor. Background materials extend to the edges of the display and UI elements are appropriately inset and positioned.

コードで実装する場合

AutoLayoutを使わずframeを用いて以下のように書いて実装していた場合はiPhoneXでも全画面で表示されます。

let tableView = UITableView()

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self
    view.addSubview(tableView)
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    tableView.frame = view.bounds
}

ただし、ボタンをテーブルビューの下に配置して以下のようなUIを実装していた場合、iPhoneXではボタンがSafeAreaからはみ出してしまいます。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    button.frame = CGRect(x: 0, y: view.frame.height - button.frame.height, width: view.frame.width, height:44)

    var tableFrame = view.bounds
    tableFrame.size.height -= button.frame.height
    tableView.frame = tableFrame

}

 

これはSafeAreaを意識した実装に直す必要があります。
iOS11から登場した safeAreaInsets を使えばそのビューのSafeAreaのInsetsを取れるのでこの値を加味して計算すればちゃんとSafeArea内に収める事ができます。

override func viewDidLayoutSubviews() {

    button.frame = CGRect(x: 0, y: view.frame.height - button.frame.height - view.safeAreaInsets.bottom, width: view.frame.width, height:44)

    var tableFrame = view.bounds
    tableFrame.size.height = button.frame.origin.y
    tableView.frame = tableFrame
}

またAutoLayoutを使う場合は、iOS11から新たに追加した constraintEqualToSystemSpacingBelow を使っても簡単に実装ができます。

let safeArea = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
    // ボタンの制約
    button.centerXAnchor.constraintEqualToSystemSpacingAfter(view.centerXAnchor, multiplier: 1.0),
    button.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1.0),
    button.heightAnchor.constraint(equalToConstant: 44),
    safeArea.bottomAnchor.constraintEqualToSystemSpacingBelow(button.bottomAnchor, multiplier: 1.0),
    // テーブルビューの制約
    safeArea.topAnchor.constraintEqualToSystemSpacingBelow(tableView.topAnchor, multiplier: 1.0),
    safeArea.leadingAnchor.constraintEqualToSystemSpacingAfter(tableView.leadingAnchor, multiplier: 1.0),
    tableView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1.0),
    tableView.bottomAnchor.constraintEqualToSystemSpacingBelow(button.topAnchor, multiplier: 1.0)
])

ただし、これだと結局全画面になってないし、これが見た目的にアリなのかはちょっと疑問ですね。
ボタンをフローティングにしてテーブルビューは下までスクロールするとか、ボタンの高さを広げたデザインにしてもいいかもしれません。

  
  

まとめ

所感としては、1画面をedge-to-edge対応するには制約を付け替えるくらいでそんなに時間はかからなそうですが、画面がたくさんあるとめんどくさそうです。
また、画面によってはデザインの再考の必要性もありそうなので、他のアプリが同対応していくのかもちょっと気になります。


『 Swift 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。