web-dev-qa-db-ja.com

Xcode 9の安全な領域

Xcode9 Beta Found Safe Area の探索中Interface Builderで階層ビューアを表示します。 Appのドキュメントのセーフエリアについて知りたいと思い、Gistで"Autoレイアウトと直接対話するビューエリア"と言っていますが、私を満足させるものではありませんでした。事.

何か手がかりがありますか。

enter image description here

セーフエリアに関するAppleのドキュメントからの結論段落。

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

125
dip

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

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

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

アップルによると、 Xcode 9 - Release note
Interface Builderは、UIViewControllerの廃止予定の上下レイアウトガイドの代わりにUIView.safeAreaLayoutGuideを使用します。新しいセーフエリアを使用するには、View Controllerの「ファイル」インスペクタで「セーフエリアレイアウトガイド」を選択してから、コンテンツと新しいセーフエリアアンカーの間に制約を追加します。これにより、コンテンツが上下のバーやtvOSのオーバースキャン領域によって隠されることを防ぎます。セーフエリアへの制約は、以前のバージョンのiOSにデプロイするときにTopとBottomに変換されます。

enter image description here


これは既存の(上と下の)レイアウトガイドとセーフエリアレイアウトガイドの比較(同じような視覚効果を得るため)としての簡単な参照です。

セーフエリアレイアウト:  enter image description here

オートレイアウト

enter image description here


セーフエリアレイアウトを使用する方法

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

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

これがスナップショットのサンプルです。セーフエリアレイアウトと編集制約を有効にする方法です。

enter image description here

これは上記の変更の結果です

enter image description here


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

enter image description here

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

enter image description here

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

enter image description here


これがサンプルコードです(参照: セーフエリアレイアウトガイド
コードで制約を作成する場合は、UIViewのsafeAreaLayoutGuideプロパティを使用して関連するレイアウトアンカーを取得してください。上記のInterface Builderの例をコードで再現して、外観を確認しましょう。

View Controllerのプロパティとして緑色のビューがあるとします。

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)
   ])
}


結果:

enter image description here


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 のサンプルコードです。


これが Safe Area Layout Guide のアップルデベロッパ公式ドキュメントです。


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

232
Krunal

言及したいSpriteKitベースのアプリを適応させて新しいものの丸い縁と「ノッチ」を回避しようとしたときに最初に私を捕まえたものiPhone X、最新の Human Interface Guidelines で示唆されているように、新しいプロパティsafeAreaLayoutGuide of UIViewを照会する必要がありますafter意味のあるレイアウトフレームをレポートするために、ビューが階層に追加されました(たとえば、-viewDidAppear:に)(そうでない場合は、画面全体のサイズを返すだけです)。

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

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

(エンファシス鉱山)

-viewDidLoad:と早く読んだ場合、ガイドのlayoutFrameは、予想される{{0, 0}, {375, 812}}ではなく{{0, 44}, {375, 734}}になります。

17
Nicolas Miari

enter image description here

  • IOS 7.0〜11.0の初期のバージョンでは< 非推奨 > UIKittopLayoutGuidebottomLayoutGuide を使います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ポイントです。

  • セーフエリアレイアウトガイド を有効にすると、インターフェイスビルダーにセーフエリア制約プロパティが表示されます。

enter image description here

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
        }

enter image description here

enter image description here

enter image description here

14
Jack

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

詳しくは link を参照してください。

7
Kemo

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

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

IPhone Xでは、セーフエリアは、バーが表示されていない場合でも、縦方向の画面の上下の端からの追加のインセットを提供します。ランドスケープでは、セーフエリアはスクリーンとホームインジケーターの側面から差し込まれています。

これは、Appleのビデオ「 iPhone X用の設計 」から取得されます。ここでは、さまざまな要素がセーフエリアにどのように影響するかも視覚化されます。

4
Yannick