忙しい人向けの Stacks, Grids, and Outlines in SwiftUI - #WWDC20

忙しい人向けシリーズの第18弾。

冒頭

新しい Mac の Notification Center は SwiftUI で実装されている。

画像1

シンプルな Stack / Grid を 階層・アラインメント・スペースなどと組み合わせることで、美しいデザインを実現している。SwiftUI は構成(compositional)を念頭に設計されており、単純な型で実現できないときは、他の単純な型と組み合わせることで解決する。

画像2

今日のアジェンダ。

画像3

Stacks

サンドイッチアプリを例に見ていく。画像はリサイズで表示させ、

画像4

オーバーレイとして BannerView を表示している。

画像5

BannerView は VStack を利用して、タイトル(TitleView)と評価(RatingView)を配置している。

画像6

RatingView は HStack を利用して画像を配置しているだけ。

画像7

最初の実装はシンプルで、VStack と ForEach を利用したもの。VStack は単独ではスクロールを提供しないため ScrollView でラップしている。これは機能するものの、要素数が増えると初期表示が遅くなる問題が見つかった。

画像8

遅延読込を実現する LazyVStack / LazyHStack が追加された。これらは実際に要素が表示された時にレンダリングされる。

画像9

VStack を LazyVStack に置き換えるだけで今回はOK。

画像10

ところでスターの部分では HStack を利用しているが、これらも Lazy にすべきなのだろうか?答えは No。View が画面に表示されるときは一度にコンテンツをロードする必要があるので Lazy にしても意味がない。

画像11

どちらのタイプを使うべきか判断がつかないときは、原則として VStack / HStack を利用すること。パフォーマンス上の問題が見つかった際に Lazy Stack の利用を検討すること。

Grids

画像12

ところで今回のアプリを iPad で動かすとどうなるだろう?同じように表示されるけど・・・大きい。

画像13

マルチカラムレイアウトを実現する LazyVGrid / LazyHGrid が追加された。

画像14

現状の実装はこうなっているが、これを3カラムで表示するためには・・・

画像15

このように VStack を LazyVGrid に置き換える。

画像16

現状は、カラム定義を3列に固定しているため、横向きでも同様に表示されるが・・・

画像17

カラム数を可変にすることもできる。これはウィンドウサイズが変更できる Mac などでも有効なテクニック。

画像18

Lists

List選択管理スクロールなどを提供し、デフォルトで遅延読込となっている。

画像19

ここからは ShapeEdit というアプリを例に見ていく。ここではサイドバーの項目を List を使って表現している。ここではフラットに表示しているが・・・

画像20

子となるデータを Key-path で指定することで、階層化された表示もできるようになった。

画像21

Outlines

新しく追加された OutlineGroup を利用して、このようなサイドバーをデザインできる。アウトラインは Mac 専用ではなく、iPhone / iPad でも共通して利用できる

画像22

通常の階層表示ではなく、表示・非表示したいケースもあるが、それには DisclosureGroup を利用できる。これは・・・

画像23

開示インジケーターと、

画像24

ラベルと、 

画像25

コンテンツで構成されている。

画像26

isExpanded プロパティに Binding を渡すことで、最初から開いた状態にすることもできる。ちなみに Form は MacOS の Settings のシーンでも利用できる。

画像27

これは内部的な仕組みなので理解する必要はないが、OutlineGroup は ForEach と DisclosureGroup によって実現されている。そして、子の要素があると DisclosureGroup のコンテンツに OutlineGroup を再度利用する。コンテンツは開いた時にだけ評価されるので効率的。

画像28

まとめ

・HStack / VStack は固定サイズの要素を表示するのに便利
・LazyHStack / LazyVStack は可変サイズでスクロールする際に便利
・LazyHGrid / LazyVGrid はグリッド表示に便利
・List は選択・スクロール・遅延読込、そして階層表示をサポートする
・Form は設定値などの UI に利用できる
・OutlineGroup / DisclosureGroup は開閉を実現する

画像29

他のセッションも参照のこと。

画像30

関連記事

忙しい人向けの App essentials in SwiftUI - #WWDC20

忙しい人向けの Data Essentials in SwiftUI: Part 1 - #WWDC20
忙しい人向けの Data Essentials in SwiftUI: Part 2 - #WWDC20

免責

・本記事は公開情報のみに基づいて作成されています。
・要約(意訳)のみなので、詳細はセッション動画をご確認ください。

役に立った記事などありましたらサポート頂けると嬉しいです。