WWDC Quick Look 💓 By SwiftGGTeam
Stacks, Grids, and Outlines in SwiftUI

Stacks, Grids, and Outlines in SwiftUI

元の動画を見る

ハイライト

SwiftUI 2020 が追加 LazyVStackLazyHStackLazyVGridLazyHGridList(children:)OutlineGroup そして DisclosureGroup, そのため、長いリスト、グリッド レイアウト、階層データ、インスペクター コントロールを複合ビューを使用して直接実装できます。


主要内容

コーディはサンドイッチギャラリーについて話し始めました。最初の実装は非常に自然です。 HeroView の中へ ForEach、それを層で覆います。 VStack、そして使用します ScrollView スクロールを担当します。データが小さい場合は問題ありません。写真の数が増えると、ページを開いたときに最初にすべての写真を作成して測定する必要があり、最初の画面の応答が遅くなり、メモリも増加します。

SwiftUI 2020 の答えは遅延スタックです。外側のスクロール コンテナーを次のように置き換えた後、 LazyVStack、表示されているサンドイッチ カードのみが最初の画面にレンダリングされ、後続のコンテンツはユーザーが近くをスクロールした後に作成されます。内部採点 HStack 画像オーバーレイを遅延に変更する必要はありません。 HeroView 画面に が表示されると、その中のコンテンツも同時に表示されます。

次に、同じギャラリーを iPad に移動しました。単一列の画像は大きな画面ではスペースを無駄にするため、セッションでは LazyVGrid そして LazyHGrid。開発者が使用する GridItem 列または行のサイズを記述するには、3 つの列を固定するか、次のいずれかを使用します。 .adaptive(minimum:) 利用可能な幅に応じて列数を変化させます。

後半では、macOS、iPadOS、iOS で動作するドキュメントベースのアプリである ShapeEdit に切り替えました。最初にキャンバス上にグラフィックのフラットなリストを表示するだけで済みます。 「グラフィックグループにはグラフィックグループを含めることができる」を追加すると、データは任意の深さのツリーになります。 List(children:) 子のキー パスに沿ってツリーを直接展開できます。 OutlineGroup 同じ機能をカスタム リスト構造に組み込みます。

最後にインスペクターパネルがあります。塗りつぶし、影、テキスト、その他のコントロールをすべて広げると、混雑しすぎます。 DisclosureGroup コントロールの各グループにタイトル、展開状態、およびコンテンツ領域を含めることができます。と Label およびブール バインディングでは、デフォルトの展開グループを設定することもできます。これにより、SwiftUI のレイアウトのストーリーが「ビューの配置」から「情報の漸進的な表示」に拡張されます。

詳細

遅延スタック: スクロール コンテンツは表示されている場合にのみ作成されます

(03:27) 通常 VStack すべてのサンドイッチを列挙し、対応するビューを作成します。 ScrollView が表示されます。トランスクリプト内の質問は非常に具体的です。写真が多いほど、ページが応答するまでに時間がかかります。アップルが追加した LazyVStack そして LazyHStack スクロール方向のコンテンツをオンデマンドでレンダリングできるようにします。

// Fetch sandwiches from the sandwich store
let sandwiches: [Sandwich] =

ScrollView {
    LazyVStack(spacing: 0) {
        ForEach(sandwiches) { sandwich in
            HeroView(sandwich: sandwich)
        }
    }
}

キーポイント:

  • ScrollView 引き続きスクロールを担当します。遅延スタック自体はスクロール機能を提供しません。
  • LazyVStack(spacing: 0) オリジナルを置き換えます VStack(spacing: 0)、これはパフォーマンス変化のエントリ ポイントです。
  • ForEach(sandwiches) データ駆動型の書き込みを維持し、各モデルは HeroView
  • セッションは明確に次のことを推奨します: VStack または HStack 疑わしい場合は、まず Instruments を使用してパフォーマンスのボトルネックを見つけてから、遅延スタックを使用します。

レイジー グリッド: 大画面でのコンテンツ密度を増加します。

(05:48) サンドイッチ ギャラリーを iPad に配置すると、単一列レイアウトにより画像が大きくなるだけで、画面上のコンテンツの量は増えません。 LazyVGrid そして LazyHGrid 使用 GridItem 同じデータのバッチを列または行に配置できるように、グリッド サイズを記述します。

// Fetch sandwiches from the sandwich store
let sandwiches: [Sandwich] =

// Define grid columns
var columns = [
    GridItem(.adaptive(minimum: 300), spacing: 0)
]

ScrollView {
    LazyVGrid(columns: columns, spacing: 0) {
        ForEach(sandwiches) { sandwich in
            HeroView(sandwich: sandwich)
        }
    }
}

キーポイント:

  • GridItem(.adaptive(minimum: 300), spacing: 0) 各列の幅は少なくとも 300 ポイントである必要があります。
  • LazyVGrid(columns: columns, spacing: 0) 列構成を読み取り、利用可能な限り同じ幅の列を生成します。
  • ForEach そして HeroView 変更されない場合、レイアウト コンテナーがリストからグリッドへの変更を引き継ぎます。
  • 記録では具体的に次のことに言及しています .adaptive サイズ変更可能なウィンドウを備えた横長の iPad および macOS に適しています。

子のリスト: フラットなリストを階層リストに変換します。

(08:41) ShapeEdit のサイドバーは、元々は単なるキャンバス グラフィックのリストでした。リストがツリー構造を表現する必要が生じた後も、グラフィックス グループには引き続きサブグラフィックスを含めることができます。 SwiftUI は子キーのパスを追加します List、パラメーターを使用して、データ ツリーを移動する方法をリストに指示します。

struct GraphicsList: View {
    var graphics: [Graphic]
    var body: some View {
        List(
            graphics,
            children: \.children
        ) { graphic in
            GraphicRow(graphic)
        }
        .listStyle(SidebarListStyle())
    }
}

キーポイント:

  • graphics ツリーのルート ノード配列です。
  • children: \.children 言う List ここで、それぞれの子ノードは Graphic は。
  • GraphicRow(graphic) は依然として単一行の表示のみを担当し、階層展開は によって処理されます。 List
  • SidebarListStyle() サイドバースタイルを導入します。トランスクリプトでは、iOS 14 の太字ヘッダーもこの方向でのリスト スタイルの改善から来ていると述べています。

アウトライングループ: カスタム構造でのツリー トラバーサルの再利用

(09:52) List(children:) リスト全体がツリーである状況に適しています。 ShapeEdit では、キャンバスごとに 1 つのセクションと、各セクション内のグラフィックス ツリーが必要です。 OutlineGroup 代わりに使用されます。

// Customizing your outlines

List {
    ForEach(canvases) { canvas in
        Section(header: Text(canvas.name)) {
            OutlineGroup(canvas.graphics, children: \.children)
            { graphic in
                GraphicRow(graphic)
            }
        }
    }
}

キーポイント:

  • アウター List 引き続き、選択、スクロール、リストの操作を担当します。
  • ForEach(canvases) キャンバスごとにパーティションを作成します。
  • Section(header: Text(canvas.name)) キャンバス名がセクションのタイトルに変わります。
  • OutlineGroup(canvas.graphics, children: \.children) 各パーティション内のツリー グラフィックス データを走査します。

DisclosureGroup: 非ツリー情報の展開を制御します

(13:10) インスペクターの塗りつぶし、シャドウ、およびテキストのコントロールはルール ツリー構造に属していませんが、これらも折りたたむ必要があります。 DisclosureGroup 展開インジケーター、ラベル、コンテンツを提供します。ブール値バインディングが渡された場合、デフォルトの展開を状態によって制御することもできます。

// Progressive display of information
Form {
    DisclosureGroup(isExpanded: $areFillControlsShowing) {
       Toggle("Fill shape?", isOn: isFilled)
       ColorRow("Fill color", color: fillColor)
    } label: {
       Label("Fill", )
    }

}

キーポイント:

  • Form 設定とコントロールのセットをホストするのに適しています。セッションではmacOSの設定シーンにも利用できることについても触れられていました。
  • DisclosureGroup(isExpanded:) 手を広げた状態 areFillControlsShowing
  • Toggle そして ColorRow 折りたたまれたり展開されたりする実際のコントロールです。
  • Label("Fill", …) タイトルとアイコンを組み合わせたものです。 SF シンボルのアイコンはトランスクリプトで使用されます。

重要ポイント

  • 長いコンテンツ ギャラリー: 写真、メニュー、または製品ギャラリーを作成するには、まず次のコマンドを使用します。 ScrollView そして LazyVStack 最初のバージョンの場合。最初は、既存のセル ビューを保持し、外側のみを置き換えます。 VStack、次に Instruments を使用して最初の画面の応答とメモリを確認します。

  • アダプティブ iPad グリッド: 電話機上の 1 列のコンテンツを iPad または macOS ウィンドウに移動する場合は、次を使用します。 LazyVGrid プラス GridItem(.adaptive(minimum: 300))。水平、垂直、ウィンドウの幅に合わせて複数のレイアウトを作成することを避けるために、最小の列幅から始めます。

  • ドキュメント サイドバー ツリー: アプリにフォルダー、レイヤー、キャンバス オブジェクト、またはタスク グループがある場合、モデルを公開させることができます。 children、そして使用します List(items, children: \.children) 拡張可能なサイドバーを作成します。単一行ビューはシンプルに保たれ、ツリーのトラバースは SwiftUI に任せられます。

  • パーティション化されたアウトライン エディタ: データに複数のルート コレクション (複数のキャンバス、複数のプロジェクト、または複数のアカウントなど) がある場合は、次の組み合わせを使用します。 ListForEachSection そして OutlineGroup。このようにして、各パーティションに独自のタイトルが付けられ、各パーティション内でツリーを展開することができます。

  • コンパクトなインスペクター パネル: あまり使用されないフォーム コントロールを DisclosureGroup。よく使用されるグループはデフォルトで展開されます。 isExpanded バインディング、その他のグループは折りたたまれたままなので、プロパティ パネル、設定ページ、エディターのサイドバーに適しています。

関連セッション

  • SwiftUI の新機能 — このセッションで拡張されたアウトライン、グリッド、コントロールを含む SwiftUI 2020 の概要。
  • SwiftUI のアプリの要点 — トランスクリプト 最後に指定されたフォローアップ セッションで、アプリ、シーン、設定シーンについての話が続きます。
  • Data Essentials in SwiftUI — トランスクリプト 最後に指定されたフォローアップ セッションで、モデル データがビューの更新をどのように促進するかについて話します。
  • SwiftUI でドキュメントベースのアプリを構築する — ShapeEdit はドキュメントベースのアプリのシナリオです。このセッションは、DocumentGroup とドキュメント管理基盤を補完します。

コメント

GitHub Issues · utterances