見出し画像

Build for iPadをみた #WWDC20

こちらの記事には非公開の情報が含まれているのでApple Developer Programに登録しNDAに合意している方のみ閲覧してください

昨日はDesignの方をみたので今日は実装について見ていきました。

Multi-column Split View

初期化時にスタイルを指定する。これは2列の場合。

画像1

.primaryが左側.secondaryが右側になる。

画像2

3カラムも同様。

画像3

真ん中は.supplementaryと呼ぶ。

画像4

Size Classesが.regularの場合はUISplitViewControllerで複数表示しても問題ないが、スライドオーバーやiPhoneの縦向きなど.compactな場合は横のスペースが足りない。こういった場合は特定のSize Classesの場合にViewControllerを設定することができる。

画像5

iPadやiPhone専用のUIとするのではなくSize Classesでレイアウトを変更するべき。

表示方法

画像6

2カラムの表示方法

画像7

3カラムの表示方法

左側のカラムはボタンや左端をスワイプすることで表示させることができる。この動作もコントロールすることができる。

画像8

presentWithGestureは初期値はtrueになっており、falseにするとボタンが非表示になりジェスチャーが無効になる。showsSecondaryOnlyButtonはセカンダリカラム以外の全てを非表示にするボタンを有効にする。

表示モード

画像9

.tile

画像10

.displace

画像11

.overlay

カラムの表示、非表示をコードで操作することもできる。

splitViewController.hideColumn(.primary)
splitViewController.showColumn(.suppplementary)

常に同じレイアウトである場合はpreferredDisplayModeで指定する

画像12

List

詳細は昨日のセッションにて。ここでは.primary, .supplementaryで正しい見た目にする方法を紹介する。

画像13

データの例

struct MyItem: Hashable {
    let title: String
    let image: UIImage
}

セルを登録して実行するclosureを設定する。

画像14

contentConfiguration APIを使用してセルの内容を指定する

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
}

最後にUICollectionViewDiffableDataSourceを作成する

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

結果はこのようになる

画像15

先ほどのconfigurationのappearanceを.sidebarPlainに設定すると

画像16

背景が白くなる

画像17

Listにはアクセサリーや並び替え、概要、スワイプアクションを設定することができる

Reducing modality

カラーピッカーやメニューは前面を覆うようなコンテキストを遮るようなことが無いようにした。これによりタスクを完了させるために必要なタップ数を減らすことができる。

画像18

Shortcutsアプリの例

Two column layout with Split View Controller

画像19

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

画像20

iPadのレイアウトの設計の例

let tabBarController = createTabBarController()
splitViewController.setViewController(tabBarController, for: .compact)

iPhoneの場合は1画面のタブを表示

2カラムでアプリを使用中に別のアプリを開くと1カラムになってしまうことがある。

画像21

それでもスムーズな表示を実現したい。

画像22

そこでRestorableというプロトコルに適合してリストアが呼ばれて状態が復元されることを確認する。

Sidebar

画像23

Shortcuts.appのサイドバーはコレクションビューが配置されており各項目はListCellになっている。collectionViewのLayoutのコードを見てみよう。

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

続いてセルの登録について

struct Section: Hashable { … }
struct Item: Hashable { … }

let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Item> { cell, indexPath, item in
   // Configure the cell
}

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

型安全な方法で一箇所でセルの登録と設定が可能になっている。続いてどのようにセルに設定するか見てみましょう。

let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Item> { cell, indexPath, item in
   var content = cell.defaultContentConfiguration()
   content.text = item.title
   content.image = item.image
   cell.contentConfiguration = content
}

まとめ

新しいSplit View Controllerのおかげで簡単にサイドバーの実装ができそうなイメージが沸きました。(iOS 13以下との共存はとても難しそうに感じた...)どこかで個人アプリなどでサイドバーの対応をして見たいと思います。

この記事が気に入ったらサポートをしてみませんか?