WWDC Quick Look 💓 By SwiftGGTeam
Build for iPad

Build for iPad

元の動画を見る

ハイライト

iPadOS 14 の設計目標は、タッチ操作の直感性を保ちながら、iPad によりデスクトップ級の生産性体験をもたらすことです。このセッションでは、iPadOS 14 における 4 つの主要な UI パターン更新を紹介します。

主要内容

iPad の画面は十分大きいですが、多くの iPad アプリは依然として iPhone の 1 列のナビゲーションを使用しています。ユーザーは、「メール」でメールボックスと電子メールを同時にチェックしたい、「メモ」でツールを選択しながら書き込みを続けたい、「ホーム」で部屋やデバイスをすばやく切り替えたいと考えています。古いインターフェースでは、多くの場合、続行する前にページ間を行ったり来たりしたり、ポップアップ レイヤーを閉じたりする必要があります。

iPadOS 14 では、このパスが UIKit に追加されます。UISplitViewControllerインターフェースを列ごとに編成するための新しい初期化メソッドが追加されました。アプリは 2 列または 3 列のレイアウトを直接宣言し、プライマリ、補足、セカンダリ、コンパクト、その他の列に対応するビュー コントローラーを提供できます。UIKit は、サイズ クラスに応じて適切な列を表示し、列を表示または非表示にするためのボタンとジェスチャを自動的に提供します。

列内のリストもモダンな手法に置き換わります。Apple は UICollectionViewUICollectionLayoutListConfiguration を組み合わせて sidebar 外観を作り、さらに UICollectionView.CellRegistrationUICollectionViewDiffableDataSource でセルにデータを渡すことを推奨しています。このようにして、iPadOS 14 のサイドバー スタイルを取得できるだけでなく、コレクション ビューのドラッグ並べ替え、アウトライン、スワイプ アクション、およびカスタマイズ可能なセルを引き続き使用することもできます。

セッション後半では Shortcuts を例にしています。Shortcuts は regular width では tab bar を折りたたみ可能な sidebar に置き換え、compact width では小さい画面に適した tab bar とリストを引き続き使用します。完全に分断された 2 つのアプリ構造を維持するのではなく、2 種類のナビゲーションフローを同じ UISplitViewController に入れ、size class が切り替わるときにユーザーが見ていた detail 状態を復元します。

詳細

複数列レイアウトはUISplitViewControllerから始まります

01:57)iOS 14 の UISplitViewController の新しいイニシャライザは style を受け取り、アプリに 2 列が必要か 3 列が必要かを宣言するために使用されます。2 列では primary と secondary を使い、3 列では中央に supplementary を追加します。

let splitViewController = UISplitViewController(style: .doubleColumn)

キーポイント:

  • style: .doubleColumnこの分割ビューがナビゲーション列とコンテンツ列を担当することを示します。
  • この initializer により、セッションで示された新しい列管理 API が有効になります。
  • Apple は、列で構造化されたアプリでは UISplitViewController を window の root view controller として直接使うことを推奨しています。

02:13)split view を作成したら、具体的な view controller を指定した列に配置します。Home の例では、primary に sidebar、secondary にホーム画面の内容を置いています。

splitViewController.setViewController(sidebarViewController, for: .primary)
splitViewController.setViewController(myHomeViewController, for: .secondary)

キーポイント:

  • .primary通常は、メールボックス リスト、ルーム リスト、ショートカット カテゴリなどのナビゲーション ポータルをホストします。
  • .secondary はユーザーが現在操作している主要コンテンツを担います。
  • UIKit は regular width か compact width かに応じて、これらの列の表示方法を決定します。

02:28)アプリの情報階層に 3 列が必要な場合は、style を .tripleColumn に切り替え、supplementary 列に中間層の内容を提供できます。Mail の mailbox、message list、message detail はこのモデルです。

let splitViewController = UISplitViewController(style: .tripleColumn)
splitViewController.setViewController(inboxViewController, for: .supplementary)

キーポイント:

  • .tripleColumn は、ナビゲーション、リスト、詳細が同時に存在する生産性アプリに適しています。
  • .supplementary は primary と secondary の間にある中間列です。
  • この API は構造のみを担当し、列内の特定のインタラクションは引き続きそれぞれのビュー コントローラーによって管理されます。

compact width では異なるナビゲーションフローを使える

(04:02) 標準幅では複数の列を表示できますが、コンパクト幅では水平方向のスペースが不足します。Session は、通常の幅でサイドバーを使用し、コンパクトな幅でタブ バー コントローラーを提供するというショートカットのアプローチを示しています。

splitViewController.setViewController(tabBarController, for: .compact)

キーポイント:

  • .compact列は、iPhone の縦向き、iPad の Slide Over など、幅の狭い環境で使用されます。
  • compact flow は regular width の sidebar flow と異なっていてかまいません。
  • 切り替えロジックは UISplitViewController が trait collection に応じて処理し、アプリ側はユーザーの現在位置を保つ責任を持ちます。

(05:29) 複数列インターフェイスは単なる固定レイアウトではありません。preferredSplitBehaviorボタンとエッジ ジェスチャが異なる表示モード間でどのように移動するかを決定します。

splitViewController.preferredSplitBehavior = .tile
splitViewController.preferredSplitBehavior = .displace
splitViewController.preferredSplitBehavior = .overlay

キーポイント:

  • .tile は列を横並びに配置する方向に働き、コンテンツを常に見せたいアプリに適しています。
  • .displace3 つの列が表示されると、2 番目の部分が押しのけられます。
  • .overlayナビゲーション情報を簡単に表示するのに適した、セカンダリ列をオーバーレイする追加の列を用意します。

(05:56) アプリは、列の非表示または表示をアクティブにリクエストすることもできます。UIKit はスムーズな遷移を実行し、自動生成されたボタンを各列のナビゲーション バーまたはツールバーに配置します。

splitViewController.hideColumn(.primary)

splitViewController.showColumn(.supplementary)

キーポイント:

  • hideColumn は、文書やメール本文だけを見る場合など、ユーザーを現在の内容に集中させたいときに適しています。
  • showColumnナビゲーション列または中央のリストを戻すことができます。
  • セッションでは presentsWithGestureshowsSecondaryOnlyButton にも触れており、これらはエッジジェスチャと secondary だけを表示するボタンを制御します。

(08:06) 列は単なるコンテナであり、サイドバーのリストはコレクション ビューを使用する必要があります。iOS 14 で利用可能な UICollectionLayoutListConfiguration では、sidebar 外観を直接指定できます。

let configuration = UICollectionLayoutListConfiguration(appearance: .sidebar)
let layout = UICollectionViewCompositionalLayout.list(using: configuration)
let collectionView = UICollectionView(frame: frame, collectionViewLayout: layout)

キーポイント:

  • .sidebar は primary 列に iPadOS 14 の sidebar 視覚スタイルを提供します。
  • UICollectionViewCompositionalLayout.list(using:) は垂直スクロールの list layout を生成します。
  • UICollectionViewコレクション ビューの柔軟性は引き続き維持され、後でアクセサリを追加したり、ドラッグして並べ替えたり、アウトラインやスワイプ アクションを実行したりできます。

09:36)単純なリストのために cell subclass を書く必要はなくなりました。CellRegistration は登録と構成を 1 か所にまとめ、defaultContentConfiguration() で文字と画像を書き込みます。

let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, MyItem>
{ cell, indexPath, item in

    var content = cell.defaultContentConfiguration()

    content.text = item.title
    content.image = item.image

    cell.contentConfiguration = content
}

キーポイント:

  • UICollectionViewListCell は list の場面で使う標準的な cell 型です。
  • MyItem はアプリ自身のデータ型で、セッション例では title と image を含みます。
  • defaultContentConfiguration() は現在の list/sidebar 環境に応じた適切な既定スタイルを返します。
  • 設定cell.contentConfiguration最後に、セルのテキスト、画像、パディングはシステム構成によって均一に管理されます。

10:31)最後に diffable data source でデータソースを collection view につなぎます。これは section と item に基づいて cell を生成します。

let dataSource = UICollectionViewDiffableDataSource<Section, MyItem>
   (collectionView: collectionView)
{ collectionView, indexPath, item in
   return collectionView.dequeueConfiguredReusableCell(using: cellRegistration,
                                                       for: indexPath,
                                                       item: item)
}

キーポイント:

  • SectionMyItem はリストのデータ構造を表します。
  • closure は collection view が cell を必要とするときに呼び出されます。
  • dequeueConfiguredReusableCell再利用と構成を同時に完了して、再利用識別子の手動管理を回避します。
  • Session は、ほとんどのリストがレイアウト、セル登録、および比較可能なデータ ソースの組み合わせに従うことを強調しています。

11:29)supplementary 列がナビゲーション入口ではなくコンテンツリストを表示する場合、Human Interface Guidelines は sidebarPlain を推奨しています。

let configuration = UICollectionLayoutListConfiguration(appearance: .sidebarPlain)
let layout = UICollectionViewCompositionalLayout.list(using: configuration)
let collectionView = UICollectionView(frame: frame, collectionViewLayout: layout)

キーポイント:

  • .sidebarPlainフォルダー アイテム、コレクション アイテム、メーリング リストなどのコンテンツ リストに適しています。
  • セッションでは、これは白い背景、区切り線、よりコンテンツ寄りの視覚処理を表示すると説明されています。
  • primary column では .sidebar がよく使われ、supplementary column では .sidebarPlain がよく使われます。

大文字と小文字の文字列の構造と状態をまとめたショートカット

15:35)Shortcuts の regular width 版は double column split view を使います。左側の sidebar がナビゲーションを担当し、ユーザーが項目を選択すると右側に detail が表示されます。

let splitViewController = UISplitViewController(style: .doubleColumn)

// Primary column

let sidebar = SidebarViewController()
splitViewController.setViewController(sidebar, for: .primary)


// Secondary column

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    splitViewController.showDetailViewController(DetailViewController(), sender: self)
}

キーポイント:

  • SidebarViewControllerプライマリ列に入れます。
  • サイドバーからイベントを選択しますUICollectionViewDelegatedidSelectItemAt
  • showDetailViewController は新しい detail を secondary column に配置します。
  • transcript では、Shortcuts が size class の変化時に現在の detail を再構築し、ユーザーが split view から compact width に切り替えた後に現在位置を失わないようにすると説明されています。

20:39)Shortcuts の sidebar も collection view です。section provider で現在の layout environment を読み取り、compact width では header を section の最初の item に変更し、regular width では header を表示しません。

let layout = UICollectionViewCompositionalLayout(sectionProvider: sectionProvider,
         configuration: UICollectionViewCompositionalLayoutConfiguration())

func sectionProvider(_ section: Int, environment: NSCollectionLayoutEnvironment)
-> NSCollectionLayoutSection {
    var configuration = UICollectionLayoutListConfiguration(appearance: .sidebar)

    if (environment.traitCollection.horizontalSizeClass == .compact) {
        configuration.headerMode = .firstItemInSection
    } else {
        configuration.headerMode = .none
    }

    return NSCollectionLayoutSection.list(using: configuration, layoutEnvironment: environment)
}

キーポイント:

  • sectionProvider により、各 section は環境に応じて異なるレイアウトを生成できます。
  • environment.traitCollection.horizontalSizeClassコンパクト/レギュラーの判断基準となります。
  • headerMode = .firstItemInSection により、compact width でもグループ化を表現できます。
  • NSCollectionLayoutSection.list実際のリストセクションを返します。

モダリティを減らすことがインタラクション レベルでの目標です

12:27)セッションでは、iPad アプリはタスクの流れを妨げる transient UI を減らすべきだとも強調しています。Notes の color picker はユーザーが描き始めると自動で消え、Contacts のメニューではユーザーがメニュー外をタップした後、その同じタッチでスクロールを続けられます。ここに固定の API レシピはなく、Apple が示す判断基準は、ユーザーがスクロール、描画、外部イベントへの応答など、次の操作をすでに始めているかを観察することです。

キーポイント:

  • これは、iOS 14 の UIKit によって行われたシステムレベルのインタラクションの改善です。
  • アプリ自身も、スクロール、描画、incoming events などのシグナルを観察すべきです。
  • 目標は、ポップアップを閉じる手順を先に処理させるのではなく、ユーザーが現在のタスクを続けられるようにすることです。

重要ポイント

  • データベースのアプリに 3 列読み取りモードを追加 実施内容: 「分類、リスト、詳細」を iPad の横画面インターフェイスに同時に配置します。 実行する価値がある理由: 10105 が示す .tripleColumn と supplementary column は、メール、メモ、ナレッジベース、ファイル管理のように情報階層が明確なアプリに適しています。 開始方法: UISplitViewController(style: .tripleColumn) でルートコンテナを作り、分類を .primary、アイテムリストを .supplementary、詳細を .secondary に配置します。

  • 古い tab bar ナビゲーションを折りたたみ可能な sidebar に移行する 実施内容: regular width では下部 tab bar を折りたたみ可能な sidebar に置き換え、compact width では tab bar を残します。 実行する価値がある理由: Shortcuts は sidebar によってより多くのナビゲーション入口を提供し、.compact 列では小さい画面向けのフローを保っています。 開始方法: split view に primary sidebar view controller を設定し、さらに setViewController(tabBarController, for: .compact) で幅の狭いバージョンも用意します。

  • コレクション ビューを使用してサイドバー、コンテンツ リスト、アウトラインを統合します 実施内容: iPad アプリ内の table view リストを段階的に collection view list に置き換えます。 行う価値がある理由: セッションはモダンな list 方式として UICollectionView を明確に推奨しており、accessories、ドラッグ並べ替え、outline、swipe actions を引き続き拡張できます。 開始方法: まず UICollectionLayoutListConfiguration(appearance: .sidebar) で primary sidebar を組み、続けて CellRegistrationUICollectionViewDiffableDataSource を接続します。

  • サイドバーのコンテンツ列のシンプルなルック アンド フィールを選択します 対処方法: ナビゲーション リストとコンテンツ リストを区別し、補足列をファイル、メール、またはプロジェクト リストに近づけます。 実行する価値がある理由: セッションのヒューマン インターフェイス ガイドラインによって指定されたルールは次のとおりです: コンテンツ コレクションまたはフォルダー内のアイテムにはサイドバー プレーンを使用します。 開始方法: 補足列のコレクション ビューを作成するときに使用します。UICollectionLayoutListConfiguration(appearance: .sidebarPlain)

  • タスクの流れを妨げる一時 UI を能動的に閉じる 実施内容: ユーザーが描画、スクロール、入力処理を続けたとき、役割を終えた popover、menu、transient control を自動的に閉じます。 実行する価値がある理由: セッションは Notes と Contacts を例に、余分な dismiss tap が iPad 上の連続操作を中断することを説明しています。 開始方法: アプリ内で最もよく使われる popover または menu から始め、ユーザーの次の操作シグナルを見つけ、その操作が起きた時点で一時 UI を閉じつつ元の操作を続行させます。

関連セッション

  • iPad 向けに設計 - デザインの観点から見ると、サイドバー、モーダル リダクション、入力方法、アダプティブ レイアウトは、10105 のデザイン側のサポート機能です。
  • Lists in UICollectionView — collection view list と sidebar を深く扱っており、10105 のリスト実装をさらに分解するのに適しています。
  • Advances in UICollectionView — list layout、cell registration、モダンな cell configuration を扱っており、この記事のコードパスの基礎になります。
  • 比較可能なデータ ソースの進歩 — セクションのスナップショット、アウトライン、並べ替え、サイドバー データの構成について説明し、サイドバー データ レイヤーを完成させます。
  • iOS ピッカー、メニュー、アクションを使用して構築する — iOS 14 のメニュー、ピッカー、UIAction について話すことで、モダリティを減らすためのインタラクティブな変換に関するこの記事を拡張できます。

コメント

GitHub Issues · utterances