Xcode 9の安全領域


150

Xcode9 Betaの探索中に、インターフェースビルダーのセーフエリアが見つかりました階層ビューアーを表示します。アップルのドキュメンテーションのセーフエリアについて知りたくて知りたくなったのですが、要点は「自動レイアウトと直接やり取りするビューエリア」と書いてあるのですが、満足できませんでした。この新しいことの実用的な使い方を知りたいです。

誰か手がかりはありますか?

ここに画像の説明を入力してください

セーフ領域に関するApple docの結論の段落。

UILayoutGuideクラスは、ダミービューによって以前に実行されたすべてのタスクを実行するように設計されていますが、より安全で効率的な方法で実行するように設計されています。レイアウトガイドは新しいビューを定義しません。それらはビュー階層に参加しません。代わりに、所有しているビューの座標系で長方形の領域を定義するだけで、自動レイアウトを操作できます。


1
WWDCセッションを視聴できます。すべてがそこで説明されています。名前はよくわかりません。名前にXcodeまたはInterfaceBuilderが含まれているもの。
Maik639 2017年

回答:


282

セーフエリアはレイアウトガイド(セーフエリアレイアウトガイドです。
バーやその他のコンテンツによって隠されていないビューの部分を表すレイアウトガイド。iOS 11以降では、Appleは上部と下部のレイアウトガイドを廃止し、それらを単一のセーフエリアレイアウトガイドに置き換えます。

ビューが画面上に表示されている場合、このガイドは、他のコンテンツでカバーされていないビューの部分を反映しています。ビューの安全領域は、ナビゲーションバー、タブバー、ツールバー、およびビューコントローラーのビューを不明瞭にする他の祖先で覆われた領域を反映しています。(tvOSでは、overscanCompensationInsetsUIScreen のプロパティで定義されているように、セーフエリアに画面のベゼルが組み込まれています。)ビューコントローラーのadditionalSafeAreaInsetsプロパティで定義されている追加の領域も含まれます。ビューがビュー階層に現在インストールされていない場合、またはまだ画面に表示されていない場合、レイアウトガイドは常にビューの端に一致します。

ビューコントローラーのルートビューの場合、このプロパティの安全領域は、ビューコントローラーのコンテンツの隠されている部分全体と、指定した追加のインセットを表します。ビュー階層内の他のビューの場合、安全領域には、そのビューの隠されている部分のみが反映されます。たとえば、ビューが完全にビューコントローラーのルートビューの安全領域内にある場合、このプロパティのエッジインセットは0です。

Appleによると、Xcode 9-リリースノート
Interface Builderは、UIViewControllerで廃止されたTopおよびBottomレイアウトガイドの代わりにUIView.safeAreaLayoutGuideを使用します。新しいセーフエリアを使用するには、ビューコントローラーのファイルインスペクターで[セーフエリアレイアウトガイド]を選択し、コンテンツと新しいセーフエリアアンカーの間に制約を追加します。これにより、トップバーとボトムバー、およびtvOSのオーバースキャン領域によってコンテンツが不明瞭にならないようにします。以前のバージョンのiOSに展開すると、安全領域への制約が上部と下部に変換されます。

ここに画像の説明を入力してください


以下は、既存の(上と下)レイアウトガイドとセーフエリアレイアウトガイドの比較(同様の視覚効果を実現するため)としての簡単なリファレンスです。

安全領域のレイアウト: ここに画像の説明を入力してください

自動レイアウト

ここに画像の説明を入力してください


セーフエリアレイアウトの操作方法

次の手順に従って解決策を見つけてください。

  • 有効になっていない場合は、「セーフエリアレイアウト」を有効にします。
  • スーパービューとの接続が示されている場合は「すべての制約」を削除し、安全なレイアウトアンカーですべてを再接続します。または制約をダブルクリックして、スーパービューからSafeAreaアンカーへの接続を編集します

安全な領域のレイアウトを有効にし、制約を編集する方法のサンプルスナップショットを次に示します。

ここに画像の説明を入力してください

上記の変更の結果は次のとおりです

ここに画像の説明を入力してください


SafeAreaを使用し
レイアウト設計 iPhone X向けに設計するときは、レイアウトが画面全体に表示され、デバイスの丸みを帯びた角、センサーハウジング、またはホーム画面にアクセスするためのインジケーターによって隠れないようにする必要があります。

ここに画像の説明を入力してください

ナビゲーションバー、テーブル、コレクションなど、システムが提供する標準のUI要素を使用するほとんどのアプリは、デバイスの新しいフォームファクターに自動的に適応します。背景のマテリアルはディスプレイの端まで広がり、UI要素は適切に挿入されて配置されます。

ここに画像の説明を入力してください

カスタムレイアウトのアプリの場合、特にアプリが自動レイアウトを使用し、安全な領域とマージンのレイアウトガイドに準拠している場合は、iPhone Xのサポートも比較的簡単です。

ここに画像の説明を入力してください


これがサンプルコードです(参照:セーフエリアレイアウトガイド
コードで制約を作成する場合は、UIViewのsafeAreaLayoutGuideプロパティを使用して、関連するレイアウトアンカーを取得します。上記のInterface Builderの例をコードで再作成して、どのように見えるかを見てみましょう。

ビューコントローラーのプロパティとして緑のビューがあると仮定します。

private let greenView = UIView()

viewDidLoadから呼び出されるビューと制約を設定する関数があるかもしれません:

private func setupView() {
  greenView.translatesAutoresizingMaskIntoConstraints = false
  greenView.backgroundColor = .green
  view.addSubview(greenView)
}

ルートビューのlayoutMarginsGuideを常に使用して、先行マージン制約と後続マージン制約を作成します。

 let margins = view.layoutMarginsGuide
    NSLayoutConstraint.activate([
      greenView.leadingAnchor.constraint(equalTo: margins.leadingAnchor),
      greenView.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
 ])

これで、iOS 11のみを対象としない限り、セーフエリアレイアウトガイドの制約を#availableでラップし、以前のiOSバージョンの上部と下部のレイアウトガイドにフォールバックする必要があります。

if #available(iOS 11, *) {
  let guide = view.safeAreaLayoutGuide
  NSLayoutConstraint.activate([
   greenView.topAnchor.constraintEqualToSystemSpacingBelow(guide.topAnchor, multiplier: 1.0),
   guide.bottomAnchor.constraintEqualToSystemSpacingBelow(greenView.bottomAnchor, multiplier: 1.0)
   ])

} else {
   let standardSpacing: CGFloat = 8.0
   NSLayoutConstraint.activate([
   greenView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: standardSpacing),
   bottomLayoutGuide.topAnchor.constraint(equalTo: greenView.bottomAnchor, constant: standardSpacing)
   ])
}


結果:

ここに画像の説明を入力してください


UIView拡張に続いて、SafeAreaLayoutをプログラムで簡単に操作できるようにします。

extension UIView {

  // Top Anchor
  var safeAreaTopAnchor: NSLayoutYAxisAnchor {
    if #available(iOS 11.0, *) {
      return self.safeAreaLayoutGuide.topAnchor
    } else {
      return self.topAnchor
    }
  }

  // Bottom Anchor
  var safeAreaBottomAnchor: NSLayoutYAxisAnchor {
    if #available(iOS 11.0, *) {
      return self.safeAreaLayoutGuide.bottomAnchor
    } else {
      return self.bottomAnchor
    }
  }

  // Left Anchor
  var safeAreaLeftAnchor: NSLayoutXAxisAnchor {
    if #available(iOS 11.0, *) {
      return self.safeAreaLayoutGuide.leftAnchor
    } else {
      return self.leftAnchor
    }
  }

  // Right Anchor
  var safeAreaRightAnchor: NSLayoutXAxisAnchor {
    if #available(iOS 11.0, *) {
      return self.safeAreaLayoutGuide.rightAnchor
    } else {
      return self.rightAnchor
    }
  }

}

Objective-Cのサンプルコードは次のとおりです。


セーフエリアレイアウトガイドの Apple Developer公式ドキュメントはこちらです


iPhone-Xのユーザーインターフェイス設計を処理するには、セーフエリアが必要です。セーフエリアレイアウトを使用してiPhone-Xのユーザーインターフェイスを設計する方法の基本的なガイドラインは次のとおりです


違いについてmarginsview.leadingAnchor:あなたが使用している場合let margins = view.layoutMarginsGuide、後で使用するmargins.leadingAnchor、あなたはにビューを制約しているマージンビューの。これにより、側面に余分なスペースが追加されます。それが必要ない場合は、そのまま使用するview.leadingAnchorview.trailingAnchor、左側または右側に空白が表示されません...
Honey

あなたが意味するものではありません「ビューの安全なエリアは、View Controllerのビューをあいまいナビゲーションバー、タブ・バー、ツールバー、およびその他の祖先がカバーするエリア反映」ではないカバーを?その文書は「バーや他のコンテンツによって隠されていない」と述べています。
Honey

Xcode 10.1で、全画面表示でセーフエリアが画面の下部まで拡張されないという奇妙な動作を見ました。「タブバー」を誤って下部にドラッグしてから削除したことが原因だと思います。この行は、テキストエディタで手動で削除した.storyboardファイルで見つかりました。<simulatedToolbarMetrics key = "simulatedBottomBarMetrics" />。これはそれを修正しました。
デイブハバード

20

私が言及したい最新により示唆されるように、私は、丸いエッジと新しいiPhone Xの「ノッチ」を避けるためにSpriteKitベースベースのアプリを適応しようとしていたときに最初に私をつかまえた何かをヒューマンインターフェイスガイドライン新しいプロパティ:safeAreaLayoutGuideUIViewニーズをします意味のあるレイアウトフレームを報告するために、ビューが階層に追加された(たとえば、で-viewDidAppear:)照会され ます(それ以外の場合は、全画面サイズを返します)。

プロパティのドキュメントから:

バーやその他のコンテンツによって隠されていないビューの部分を表すレイアウトガイド。 ビューが画面上表示されている場合、このガイドは、ナビゲーションバー、タブバー、ツールバー、およびその他の祖先ビューでカバーされていないビューの部分を反映しています。(tvOSでは、安全領域は画面のベゼルで覆われていない領域を反映しています。)ビューが現在ビュー階層にインストールされていないか、まだ画面に表示されていない場合、レイアウトガイドの端はビューの端と同じです。

(強調鉱山)

あなたは早くもそれを読めば-viewDidLoad:layoutFrameガイドのは次のようになります{{0, 0}, {375, 812}}代わりに、期待の{{0, 44}, {375, 734}}


こっちも一緒。私は常に、ドキュメントを完全に読まずに、タイプの利用可能なプロパティに名前を付けてジャンプします...
Nicolas Miari

18

ここに画像の説明を入力してください

  • iOS 7.0–11.0の以前のバージョン<非推奨 > UIKitは、プロパティであるtopLayoutGuideおよびbottomLayoutGuideを使用しUIViewます
  • iOS11 + は、プロパティでもあるsafeAreaLayoutGuideを使用しUIViewます

  • ファイルインスペクタの[ セーフエリアレイアウトガイド]チェックボックスを有効にします。

  • 安全な領域は、インターフェース全体の可視部分にビューを配置するのに役立ちます。

  • ではtvOS、安全なエリアは、画面のベゼルによって覆われた領域を表す画面のオーバースキャンインセットを、含まれています。

  • safeAreaLayoutGuideは、ナビゲーションバー、タブバー、ツールバー、およびその他の祖先ビューで覆われていないビューの部分を反映しています。
  • 安全な領域を使用して、コンテンツのレイアウトUIButton などを支援します。

  • iPhone X用に設計するときは、レイアウトが画面全体に表示され、デバイスの丸みを帯びた角、センサーハウジング、またはホーム画面にアクセスするためのインジケーターによって隠れないようにする必要があります。

  • 背景がディスプレイの端まで伸びており、テーブルやコレクションなどの垂直方向にスクロール可能なレイアウトが一番下まで続いていることを確認してください。

  • ステータスバーは、iPhone Xでは他のiPhoneよりも高くなっています。アプリがステータスバーの下にコンテンツを配置するために固定のステータスバーの高さを想定している場合は、ユーザーのデバイスに基づいてコンテンツを動的に配置するようにアプリを更新する必要があります。音声録音や位置追跡などのバックグラウンドタスクがアクティブな場合、iPhone Xのステータスバーは高さを変更しないことに注意してください print(UIApplication.shared.statusBarFrame.height)//44 for iPhone X, 20 for other iPhones

  • ホームインジケーターコンテナーの高さは34ポイントです。

  • Safe Area Layout Guideを有効にすると、インターフェイスビルダーにセーフエリア制約プロパティが一覧表示されます。

ここに画像の説明を入力してください

それぞれに制約を設定できます self.view.safeAreaLayoutGuideように

ObjC:

  self.demoView.translatesAutoresizingMaskIntoConstraints = NO;
    UILayoutGuide * guide = self.view.safeAreaLayoutGuide;
    [self.demoView.leadingAnchor constraintEqualToAnchor:guide.leadingAnchor].active = YES;
    [self.demoView.trailingAnchor constraintEqualToAnchor:guide.trailingAnchor].active = YES;
    [self.demoView.topAnchor constraintEqualToAnchor:guide.topAnchor].active = YES;
    [self.demoView.bottomAnchor constraintEqualToAnchor:guide.bottomAnchor].active = YES;

迅速:

   demoView.translatesAutoresizingMaskIntoConstraints = false
        if #available(iOS 11.0, *) {
            let guide = self.view.safeAreaLayoutGuide
            demoView.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
            demoView.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
            demoView.bottomAnchor.constraint(equalTo: guide.bottomAnchor).isActive = true
            demoView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
        } else {
            NSLayoutConstraint(item: demoView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: demoView, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: demoView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: demoView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
        }

ここに画像の説明を入力してください

ここに画像の説明を入力してください

ここに画像の説明を入力してください


この箇条書きガイドは非常に便利ですが、「安全領域がナビゲーションバー、タブバー、ツールバー、および他の祖先ビューをカバーしていない」とはどういう意味ですか?
Chewie The Chorkie

1
例-上記の最後の画面のように、safreAreaGuideでカバーされないツールバー(今日、カレンダー、受信トレイ)
Jack

8

Appleは、iOS 7でUIViewControllerのプロパティとしてtopLayoutGuideとbottomLayoutGuideを導入しました。これらにより、ステータス、ナビゲーション、タブバーなどのUIKitバーによってコンテンツが非表示にならないようにする制約を作成できます。これらのレイアウトガイドはiOS 11で廃止され、単一のセーフエリアレイアウトガイドに置き換えられました。

詳細については、リンクを参照してください。


5

セーフエリアレイアウトガイドは、コンテンツとコントロールを配置するときにシステムUI要素が重複しないようにするのに役立ちます。

安全領域は、ステータスバー、ナビゲーションバー、ツールバーまたはタブバーであるシステムUI要素間の領域です。そのため、アプリにステータスバーを追加すると、セーフエリアが縮小します。ナビゲーションバーをアプリに追加すると、セーフエリアは再​​び縮小します。

iPhone Xでは、セーフエリアは、バーが表示されていない場合でも、縦長の画面の上端と下端から追加のはめ込みを提供します。横向きでは、セーフエリアは画面の側面とホームインジケータから差し込まれます。

これは、Apple XのiPhone Xデザインのビデオから取られたもので、さまざまな要素がセーフエリアにどのように影響するかを視覚化しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.