View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

その他のビデオ

ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。

  • 概要
  • トランスクリプト
  • コード
  • SwiftUIのご紹介

    宣言型プログラミングの世界を探求しましょう:フル機能のSwiftUI Appを一から構築する方法、そしてSwiftUIとXcode両方の力を合わせ、優れたAppをより短時間で構築する方法もお伝えします。

    リソース

    • SwiftUI
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC23

    • SwiftUIでのデザイン

    WWDC20

    • Swift UIにおけるデータの重要事項
    • SwiftUIにおけるAppの重要事項
    • SwiftUIの新機能

    WWDC19

    • SwiftUIでカスタムビューを構築する
  • このビデオを検索

    こんにちは WWDCへようこそ

    “SwiftUIの紹介” 私はジェイコブです 後ほどカイルも登場しますよ SwiftUIをご紹介するのが楽しみです Appをより早く構築する素晴らしい方法です SwiftUIについて知るには 実際に見るのが一番です SwiftUIは魔法のようですが トリックはありません Appを作りながら プロセスをご説明します どんなAppを作りましょうか カイルと私はサンドイッチが大好きです そこでサンドイッチを リストから選べるAppにしました Xcodeで構築を始めましょう

    まず新しいプロジェクトを作成

    マルチプラットフォームの Appテンプレートを使用します

    プロジェクト名は“Sandwiches”

    新規プロジェクトにはiOSとMac OS向け 両方に必要なものがすべて備わっています iOS専用アセットのグループと Mac OS専用アセットのグループです

    ただ ほとんどは共有グループにあります これがApp全体の コードです 短すぎるように思えますが これだけで十分です このコードは後で使います Appビュー用の コードから始めましょう

    エディタの左側にはコード 右側にはキャンバスがあり コードを視覚的に表示します SwiftUIではビュー定義は Swiftコードのみです キャンバスとコードエディタは 同じコードを異なる方法で表しています キャンバス上で何かを選択すれば コードにも反映されます コードを変更すると

    キャンバスにも反映されます シームレスに連携し 自由に切り替えが可能です 詳しい仕組みを説明します キャンバスには プレビューが表示され 編集やコードの確認もできます Xcodeはコードをコンパイルして実行 プレビューを表示します プレビューもSwiftUIコードを使って 作成されています 後ほど プレビューのカスタマイズに いかに有効かお見せします それでは サンドイッチのListの セルを作成しましょう この下に別のテキストを追加して 各サンドイッチの詳細を表示します ライブラリから追加します

    キャンバスにドラッグするだけです

    Xcodeでは どこに置いたら どうなるかも確認できます ドロップするとプレビューが更新され 追加テキストが表示されます テキストを追加するコードも 書き加えられました

    これらのビューは VStackに埋め込まれています VStackはSwiftUIの一般的な レイアウトコンテナの一つで ビューを垂直に配置します ビューを水平に配置するのが HStackです

    スタックの中には ビューを自由に配置できます

    このプレースホルダに サンドイッチの材料を入れます ここではハードコードされた値にします

    次にテキストの横に画像を入れましょう エディタ同様 簡単にコードを編集できます HStackにビューを埋め込みます ビューをコマンドクリックして “Embed In HStack”を選択します

    その作業のためのコードが追加されました これで VStackの横に 画像を追加できます

    あとでアセットを追加しますが ここではSFシンボル画像を使用します

    基本のセルができたので 次にセルのスタイルを設定します ビューをコマンドクリックすると プロパティを確認できます

    VStackのアライメントを変更します

    対応するコードが更新されます

    材料のテキストを見てみましょう キャンバスを使います

    コントロールキーとオプションキーと クリックでインスペクタへ行けます

    フォントを小さくしましょう サブヘッドラインを使います

    Xcodeでコードを編集すると SwiftUIの理解が深まります これがテキストのフォントを 設定するコードです このメソッドは“モディファイア”といって SwiftUIでビューの外観や動作を カスタマイズするのに使われます コードに別のモディファイアを追加して 文字色をセカンダリカラーに設定します

    それではセルをListにしましょう セルをコマンドクリックして “Embed In List”を選びます

    同じセルが5つ並んだListができます これがListにするコードです デリゲートやデータソースはなく Listのビューだけです ここにデータをつなげてみます

    既存のアセットとモデルファイルを ドラッグします

    このファイルには情報が入っています SwiftUIで使用するため タイプをIdentifiableにします

    これでListアイテムの識別ができます IDプロパティはすでにあります

    この中のテストデータは Appのデバッグに使えます

    ビューに戻り データを渡しましょう

    sandwichesに ビューのプロパティを追加します

    プレビューでは 独自のテストデータが使用できます ここにテストデータを渡します

    プレビューの上に バナーがあるのに気づきましたか プロパティの追加など 大きな変更を加えると Xcodeは更新再開の準備が整うまで プレビューを停止します このボタンをクリックすると再開できます

    次にListを動かしましょう Listにsandwichesを渡します

    テキストを更新してサンドイッチの名前と

    実際の材料の数を表示させます

    サンドイッチのサムネイル画像も 表示させましょう

    セルの変化に気づきましたか? 始めのセルの高さは44ポイントでしたが 画像が大きくなると それに合わせて セルが自動的に拡張されます 追加作業は不要です コンテキストの画像は シャープに見えるので モディファイアを使って 角に丸みを付けましょう

    使用可能なモディファイアが分からない場合は Xcodeライブラリで探せます

    cornerRadiusモディファイアを検索し キャンバスにドラッグします

    Listセルにあるビューの場合 セルが同じ定義を共有しているので モディファイアはすべてのセルに適用されます

    画像にドロップして 値を調整しましょう

    セルとListはよくなりましたね 次は セルをタップして サンドイッチの詳細が見えるようにします

    そのためにNavigationViewで Listを囲いましょう

    NavigationViewを使えば App内を移動できます iPhoneではナビゲーションバーが表示され ナビゲーションスタックに プッシュできます ビューのnavigationTitleを設定して バーに“Sandwiches”と表示させます

    次にスタックにプッシュする セルを構成します それには セルの中身を NavigationLinkで囲います

    NavigationLinkには プッシュ先を取り込みます ここではサンドイッチの名前を表示する テキストにします

    そしてセルを NavigationLinkの中に入れます

    UIが更新され すべてのセルに 詳細インジケータが表示されました SwiftUIは詳細を自動的に処理するので UIがデフォルトで正しく表示されます セルの動作確認をする時にも プレビューが便利です プレビューのプレイボタンをクリックし ライブにすると キャンバスで実際のコードを操作できます セルをタップして想定通りに 動作するか確認ができます

    スワイプしてポップすれば SwiftUIによる高度な動作を確かめられます セルは強調表示されており スワイプすると自動的に解除されます

    あとはListにサンドイッチの数を 表示させたいと思います コードが大きくなってきたので 単一のビューにはしたくありません セルを独自のビューに抽出し 分けることにしましょう Xcodeでは簡単な操作で行えます 目的のビューをコマンドクリックし “Extract Subview”を選択します

    ビューコード全体が 新しいビューに移動 名前も付けられます “SandwichCell”としましょう

    sandwichのプロパティを追加し

    そのsandwichを渡します

    これはすばらしい改善です SwiftUIではビューが非常に軽いので ビュー追加のために カプセル化や ロジック分けは必要ありません Listコードがスリム化されたので サンドイッチの数を追加しましょう

    現在は単一のコレクションを 使用していますが これはデータ駆動型のListに最適です SwiftUIを使えば 静的コンテンツと 動的コンテンツを混在させられます 現在のコレクションを ForEachに置き換えてみます

    ForEachは各アイテムのビューを作成します

    データ駆動型の要素に 静的要素を追加できました ここにもう1つテキストを追加して サンドイッチの数を表示します

    文字色をセカンダリカラーに変更します

    テキストを中央に配置するために HStackにテキストを埋め込みます

    スペーサーを追加

    スペーサーは SwiftUIのレイアウト要素です ツールバーの フレキシブルスペースのように 拡張してスペースを埋めます 2つのスペーサーがスペースを分割し テキストを中央に配置します

    次に詳細ビューを作りましょう 新しいビューを作ります SwiftUIビューテンプレートを使用し “SandwichDetail”と名付けます

    自動的にビュー構造と プレビューコードが生成されます

    サンドイッチの詳細情報を 表示するために入力として渡します

    ここでもプレビューコードを使用して テストデータを渡します

    それからサンドイッチの画像を 追加します

    画像が表示されましたが 大きすぎます デフォルトでSwiftUIは 画像を元のサイズで表示します 画質が落ちることを避けるためです しかし今回のように サイズを小さくしたい時には resizableというモディファイアを使います

    サイズは合いましたが 画像の縦横比が変わってしまいました 別のモディファイアを使って 縦横比を調整しましょう

    ここで“fill”を選ぶと 画像がフレーム全体に拡大され “fit”を選ぶと 画像がフレーム内に収まります プレビューを使えば 簡単に違いを確認できます “fit”を選んで 全体を表示させましょう

    次にListへ戻り セルを更新して 詳細ビューをプッシュします

    SandwichDetailを作成

    sandwichに渡します

    プレビューをライブにします セルをタップすると 画像が表示されます

    ただ ナビゲーションバーに タイトルを設定していなかったので 詳細ビューに戻って修正します

    ここでもnavigationTitleを追加し サンドイッチの名前を設定します

    プレビューには 表示されていませんが すぐに変更を確認したいです SwiftUIのビューの全機能は プレビューでも利用可能です 他と同じようにNavigationViewに プレビューを設定します

    プレビューのナビゲーションバーに タイトルが表示されました

    私がサンドイッチを選ぶ時 重要なことがあります ソースの量が適切であるかです 多すぎても少なすぎても おいしくありません この画像でソースは見えますが 適量かを知りたいと思います 縦横比をfillにすると

    アップで見られます よさそうですね fillとfitを切り替えることで アップと全体を交互に表示させることができます しかしApp実行中に 切り替えたい場合は どうすればよいでしょうか それを理解するにはSwiftUIのビューを もっと知る必要があります カイルに説明を変わりましょう ありがとう ジェイコブ こんにちは SwiftUIチームのカイルです SwiftUIは他のフレームワークと 少し異なります そのため 先に進む前に まずはビューの動作について説明します SandwichDetailビューを 実装したところまでお見せしました

    SwiftUIではビューは ビュープロトコルに準拠する構造体で UI Viewのように 基本クラスを継承していません つまり 保存されているプロパティを 継承しないのです スタックに割り当てられ 値で渡されます

    SandwichDetailには サイズや重さだけが保存されていて 追加の割り当てや 参照カウントはありません

    SwiftUIは裏で ビュー階層を積極的にまとめ レンダリング用のデータを作っています そのためSwiftUIでは 小さな単一目的のビューを自由に使えるのです

    私がお伝えしたいのは SwiftUIのビューは 驚くほど軽いということです SwiftUIコードはどんどん リファクタリングしてください サブビューの抽出に オーバーヘッドがないためです SwiftUIのビューの主な役割は 従来のUIフレームワークと同じです つまり UIを定義します ビュープロトコルに必要なのは bodyのみです body自体がビューです

    小さなビューを合わせて 大きなビューを構築します SandwichDetailビューでは 画像を使用しました 解像度が元のままの画像を

    resizableで画面のサイズに 合わせて調整 さらにaspectRatioを組み合わせ 画像の縦横比を合わせました

    ビューのレンダリングは そのbodyのレンダリングにすぎません

    bodyの実装に設定したブレークポイントで デバッガが停止した場合 新しいレンダリングが必要だと 判断されたことを意味します

    この通り レンダリングのタイミングは フレームワークが知っています UIの定義に加えて ビューは依存関係も定義しているからです

    SandwichDetailを拡張して ユーザーがタップすれば 画像の大きさの切り替えが できるようにしましょう

    まず必要なのは状態変数です 画像がズームされているかを示します

    SwiftUIでは 状態変数を持つビューは ビューの代わりに 変数にストレージが割り当てられます

    その状態変数に基づき フィルまたはフィットを行います ズーム時はこのように表示され ズームなしではこうなります

    タップの動作だけで 2つの状態を切り替えることができるのです タップで画像が拡大されフィルになったり

    縮小されフィットになったりします

    何が起きたのかご説明します

    SwiftUIは状態変数の 読み取りや書き込みを観測できます ズームされた箇所が bodyに読み込まれたと知っているため ビューのレンダリングが bodyに依存すると認識できます

    変数の変更に伴い フレームワークは再度bodyを要求し 新たな状態値を用いて レンダリングを更新します 別のコンテンツモードで試します 従来のUIフレームワークでは 状態変数と 単純な古いプロパティを区別できません しかしその2つの違いは明確なのです SwiftUIはUIのあらゆる状態を把握します スクロールビューのオフセットや ボタンのハイライト ナビゲーションスタックの内容もです

    これらは“真実のソース”と呼ばれる 信頼度できるデータから取得されます

    状態変数とモデルが合わさって App全体の真実のソースを構成します

    先述のとおり 縦横比を呼び出すとビューが作成されます

    コンテンツモードが 単純な古いSwiftプロパティの場合の定義では

    すべてのプロパティを 真実のソースまたは派生値に分類できます

    ズーム時の状態変数は真実のソースです

    コンテンツモードプロパティは 状態変数から派生します

    SwiftUIは状態変数の 読み取りと書き込みを観測できるため 変更があっても レンダリングが適切に更新されます

    フレームワークが新たなbodyを要求し レンダリングを更新すると 新たに縦横比ビューが作成されます そしてコンテンツモードや 保存済みプロパティが上書きされます

    こうしてすべての派生値が SwiftUIで最新の状態に維持されます

    すべての状態変数は 読み書き可能な真実のソースですが

    すべての単純な古いプロパティは 読み取り専用の派生値です SwiftUIは 読み書き可能な派生値を渡すツール “binding”を発明しました 技術的にはどの定数も 読み取り専用の真実のソースとして機能します プレビューを駆動するテストデータが その一例です

    先述のとおり 状態変数とモデルで構成されたものが App全体の真実のソースです 後ほど 観測可能なオブジェクトを使って SwiftUIにモデルオブジェクトの変更を 観測させます

    プリミティブの違いが まだ明確でなくても大丈夫です

    どのデータフロープリミティブをいつ使うべきか 直感的に分かるよう説明します まずは一歩戻って 現状を把握しましょう 先ほどの例では 従来のUIフレームワークとは全く異なり ビュー自体が持続し すべてを最新かつ 一貫性のある状態に保っていました

    これは従来のUIフレームワークでは 不可能でした 従来はビューがデータを読み取るたびに 暗黙的な依存関係になりました データの変更に応じてビューを更新し 新しい値を反映させる必要があるためです

    それが失敗するとバグになります SwiftUIは依存関係を自動的に管理します 適切な派生値を再計算し バグが再び発生しないようにするのです 一度に1つの依存関係を管理する だけではありません

    私たちが扱っているUIは大きくて複雑です 皆が頭を抱えるほど 間違いを犯しやすい状態であり 依存関係を手動で管理するのは 非常に困難です 最善を尽くした末に Appを出荷しているものの どれもUIバグの修正が必要になりました これらの線は依存関係を表しています

    すべての線を理解していても イベントハンドラのコールバックでの すべての順序で UIが一貫した状態かを 確認する必要があります

    UIKitに実装された 旧バージョンの サンドイッチAppのバグを例に説明します ビューコントローラコードのスケッチです ズームすると 拡大ボタンが表示されます

    このような低解像度の画像が 表示された場合でも サンドイッチのソースが適量だと 確認できました

    ボタンを押すと機械学習操作が バックグラウンドスレッドに送られ 画質を向上させます

    よく見えます ブラウンマスタードソースですね 1つだけ問題がありました 停止しないアクティビティインジケータが 報告されたのです

    バグの原因は イベントの予期しない順序付けです

    この手のバグは真実のソースを更新し UIを派生させる時ではなく イベントハンドラのコールバックで サブビューを直接変更する時に起きます

    原因は すぐに思い浮かぶハッピーパスに コードを記述し アンハッピーパスを見落としたことです

    問題なのは イベント数の増加につれて アンハッピーパスの数が急増することです イベントを4つ取得する際 何通りの順序があるでしょうか 4つのイベントハンドラを呼び出す順序は 24通りあります

    各イベントは複数回発生し得るので 実際の数はさらに増えます ユーザーが拡大ボタンを押すとします その複雑度を管理することの難しさは 非同期コールバックの調整や 割り込み可能な アニメーションの実装をした人はご存じでしょう これらの完了ハンドラは予期せず起動しがちです

    5年前の自分に対し 仕事について1つ言えることは UIプログラミングは難しいということです マルチスレッドコードの同期には 誰もが苦労します 数ヵ月かけて マルチスレッドコードのバグを修正しても その正確さに100%の自信を持てませんでした 多くのUIコードでそのような状態です ビューの欠落や場所の間違いと見なされるため UIコードの難しさが軽視されがちです 競合状態とUIの不統一に共通するのは 複雑さの根本的な原因です つまり見落としがちな順序付けです 多くのビューで 4つ以上のイベントを 処理する必要があります モデル通知やターゲットアクションや デリゲートメソッド ライフサイクルチェックポイントや 完了ハンドラなどです

    12個のビューには 大まかに12の階乗分の順序が存在します つまり約5億通りです これは脳での ビッグ・オー記法のようなものです

    人間の頭に一度で収まる情報量を 横線で示したとします 点線は皆さんのAppを表します

    2点の差が表すものは何でしょう

    それはバグです

    機能を追加すると 存在し得る順序付けの数が急増し それが一定数を超えると バグを避けられない状態になります

    従来のUIフレームワークを使用している時に ビューの更新を1つのメソッドに収集し 単純化する方法はご存じでしょう

    これにより曲線の上昇は抑えられます メソッドが1つの場合 呼びせる順序は1つだけだからです

    このパターンでは UIに存在し得るすべての状態に対し 真実のソースを定義する必要があります そして真実のソースから ビューのプロパティを派生させます

    SwiftUIはこのベストプラクティスに 直接影響を受けています bodyを唯一のエントリポイントにすることで フレームワークにコード化しています

    こうして複雑なケースを解決できました 従来のUIフレームワークでは このパターンの運用が難しかったケースもです 例えばサブビューの削除や ナビゲーションスタックへのプッシュ テーブルビューへの更新の実行などです

    こうして ビューに加え Appやシーン bodyを含むその他の SwiftUIの抽象化が機能します

    変化したUIの新しいインスタンスを 単純に取り出すこのパターンが 皆さんの脳に対応します UIの不整合を事実上排除します それではデモに戻り サンドイッチの詳細ビューを終了しましょう 次はサンドイッチを拡大する プロパティを追加しましょう

    “zoomed”と呼ばれ デフォルトでは“false”になります

    ビューの実装内でのみアクセス可能にするため 状態は非公開にします

    ズーム時の“fill”とそれ以外の時の“fit”の 切り替えのため 縦横比のコンテンツモードで使用します

    最後にズーム状態を切り替えるため タップジェスチャを追加します

    ライブプレビューで確認します

    モードの切り替えが可能です

    ズームインすると 下に空白が表示されます SwiftUIではセーフエリアと呼ばれる場所に ビューが自動的に配置されるのです AppのUI要素は 角の丸みによりクリップされません しかし エッジからエッジまでの画像を 画面全体に拡大したい場合

    モディファイアを追加するだけで セーフエリアの無視が可能です

    特に下端では無視してください

    ズームできましたが何かが足りません

    そこで SwiftUIアニメーションを追加します withAnimationで変更を囲います

    異なる状態の間をアニメーションにします

    アニメーションはインタラクティブでの 割り込みも可能です いつでもタップすることができ 常に正しくアニメーション化されます

    次に拡大ボタンを追加します カイルが作業したモデルでは 表示した1つの画像のみで機能しました そこで 便利な機能を追加します カイルはスパイシーなサンドイッチが好きです

    サンドイッチがスパイシーかどうかを 確認するため 詳細ビューの下にインジケータを表示します

    既存のサンドイッチ画像の周りに VStackを追加します

    そして 一般的なモディファイアを移動し VStackに適用します

    ここに画像とテキストを表示するには Labelを使用します

    Labelに“スパイシー”という タイトルを入れます

    アイコンも関連付けています “flame.fill”と呼ばれる システム画像を使用します

    Labelにはアイコンとタイトルが 一緒に表示されます リストやメニューなどの 他のコンテキストでも使用可能です Labelの外観 間隔 サイズが 自動的に変更されます

    画面の下部に背景がある 下部バナーを作りたいと思います スペーサーを追加するだけで

    バナーが下に移動し 画像が上に配置されます

    画像を中央に配置するには 画像の上に別のスペーサーを追加します

    スペーサーは要素間のパディングを維持するため 自動的に最小サイズとなります この場合 画像がコンテナの端まで 移動できるように minLengthをゼロに設定しましょう

    バナーにパディングも追加します 表示している時にスペースができるので 画面の端にぶつかりません

    インスペクターをクリックすると

    ビューのパディングをオンにできます

    見やすくなりました フォントサイズも大きくします

    テキストサイズだけでなくシンボル画像も 大きくなるので注意が必要です シンボル画像はテキストと同じフォント情報を 自動的に使用します ヘッドラインフォントを使ってみましょう

    次に スパイシーさを表現するため 赤い背景にします

    backgroundモディファイアを使用すると 適用先ビューの後ろに 任意のビューを配置できます これらはビューに単色の背景を与えるために 単色で使用されます

    ビューの背景が赤くなったのは 小さな範囲だけです

    SwiftUIでは表示サイズは コンテンツに合わせて調整されています この場合 画像とテキストは自然なサイズになり 適用したパディング用のスペースもあります スペーサーとHStackを追加することで エッジからエッジまでの拡張が可能になります

    最後に文字色を黄色にして スパイシーなテーマに合わせます

    スモールキャップを使用するために フォントを更新します

    いいですね スパイシーなサンドイッチの場合にのみ バナーを表示したいと思います 宣言構文の“IF”を使用することで 簡単にできます

    サンドイッチがスパイシーな場合は

    バナーを表示します

    表示を確認するには プレビューデータを変更し スパイシーでない別のサンドイッチを表示します 複数のバージョンを表示するように プレビューを設定することも可能です プラスボタンをクリックすると プレビューのコピーを追加できます

    使用しているデータを更新し

    様々なサンドイッチを表示することができます スパイシーなバナーを含むビューと 含まないビューの確認が可能です

    編集を行う際に ビューの両方のバージョンが確認可能です

    Xcodeで別のプレビューを追加するには ビューの別の具体例を追加するだけです

    拡大した時に このバナーがサンドイッチ画像の 邪魔にならないように変更します ズーム時に画像を非表示にするには 条件を更新するだけです

    ズームすると バナーは非表示となります

    アニメーション化して フェードインとフェードアウトも可能です

    別のtransitionを設定し アニメーション動作のカスタマイズができます

    下端で“.move”を使用してみましょう

    スライドアウト スライドインができます

    アニメーションが続いている時にタップすると

    アニメーションが向きを変えて戻ります すべてがインタラクティブで 常に正しい位置で終了します 詳細ビューで作成したものを確認します 表示するサンドイッチで構成されています これは親ビューによって渡される派生値です ズームを確認する状態プロパティもあります フレームワークによって永続化され 縦横比のコンテンツモードを制御します

    バナーはスパイシーなサンドイッチで ズームされていない場合にのみ表示されます

    スライドインとスライドアウトを行うための transitionも指定します transitionの間に 何が起きているのでしょうか? 削除するとビューは新しい位置の オフスクリーンにアニメーション化されます SwiftUIはアニメーション終了まで待機して 階層からビューを実際に削除します そして 戻った時に SwiftUIがオフスクリーンを挿入し アニメーションで元の位置に戻します アニメーションを使用し階層構造から ビューの追加や削除が簡単にできます

    このアニメーションは箱から出して すぐにインタラクティブにできるのです

    イベント駆動型ではなく データ駆動型の長所です 先ほどカイルが説明したイベントは アニメーション化中にも 発生する可能性があります アニメーションの開始と終了では さらに多くのイベントがあります このようなものをイベント駆動型の世界で 構築するのは非常に困難ですが SwiftUIではコードの1行にすぎません

    サンドイッチのListに戻り このAppを仕上げます

    ここまではマルチプラットフォームの Appテンプレートを使用した― iPhoneの作業を説明しました 他のプラットフォームでの作業もご紹介します 実行先をiPhoneからiPadに切り替えます

    そして ライブにします

    SwiftUIはナビゲーションビューを 分割ビューに変換しました 左側でサンドイッチを選ぶと 右側に表示されます

    サンドイッチを選択していない場合 空白エリアしか表示されないため サンドイッチの選択を可能とする プレースホルダーを示すには ナビゲーションビューに2つ目のビューを 追加するだけです

    複数のビューを スタックに追加することができます

    それらのビューをスタックするかわりに ナビゲーションビューが付与されます

    この場合 最初のビューが左側に表示され 2番目のビューが 右側のビューのプレースホルダになります iPhoneでは プレースホルダは自動的に削除されます

    次にMac OSを見てみましょう

    iPadと同じプレースホルダが 表示されています

    すべてのAppleプラットフォームで 同じビューコード モデルコード― そして アプリコードを使用できます また プラットフォーム特有の改善を 加えることも可能です

    サンドイッチのListを変更可能とするため 編集サポートを追加し データモデルをもう少し現実的なものとします 現在 Appのデータは 完全に静的です サンドイッチの配列を作りましたが この配列は常に必要となります モデルを更新し サンドイッチを含む ルートストアオブジェクトを作成し― 時間の経過とともに 変更できるようにします

    サンドイッチストアを使って 事前に作成された モデルファイルをドラッグします

    サンドイッチを販売する場所ではなく データストアのようなストアです

    サンドイッチを含む変更可能な オブジェクトであることに注意します

    単集合インスタンスも テスト用に用意しています 目的を変更する時には SwiftUIへの指示が必要です

    ObservableObjectプロトコルに準拠します

    次に@Publishedで確認したいプロパティに マークを付けます

    新しいモデルをどのように使用するのでしょう?

    @Stateを使用し 値に関する 真実のソースを作成したのと同様に

    @StateObjectを使用し 変更可能な オブジェクトの真実のソースを作成します

    StateObjectはビューの変更時に自動的に オブジェクトを監視し ビューを更新します StateObjectを ビューコードに追加することも可能です これはApp全体のストアなので Appコードに入れた方がよいです

    Appコードでどのように モデルにリンクできるかを確認します

    最初に使用したコードです 先ほどのビューコードと 似ていることに注目してください Appプロトコルに準拠する 構造体です bodyプロパティではビューと同様に 必要なものを構築します WindowGroupを使用して Appのすべての ウィンドウで使用するビューを指定します このAppの特徴は @main属性を持っていることです Swiftにこの構造体がAppの 出発点であることを伝えます

    ストアとStateObjectを追加します

    AppはState StateObjectと その他の特殊なプロパティが使用できます 次にストアをビューコードに渡しましょう それをビューの初期化に渡します

    ビューコードに戻ります

    定数サンドイッチを ストアのプロパティに置き換えます

    このオブジェクトを ObservedObjectにすることで 変更の監視をSwiftUIに通知します

    ストアからサンドイッチを引き出すため Listを更新します

    最後に プレビューを更新し テストストアを使用します

    ストアからデータを引き出し 編集サポートを追加する準備ができました

    スニペットからストアに変更を加えるための 便利な機能を紹介します

    新しいサンドイッチの追加や サンドイッチの移動 それに削除が行えます

    ForEachのListでは onMoveモディファイアを追加し

    “moveSandwiches”メソッドを 呼び出せます

    onDeleteを追加すれば

    “deleteSandwiches”も

    この変更を加えただけで Appに戻れます

    スワイプしてListから 行を削除することもできます 削除するとSwiftUIから コールバックが呼び出され

    ストアからサンドイッチが取り除かれます

    UIが更新されて変更が反映されます Mac OSの編集サポートに 必要なものは以上です iOSでは編集モードに切り替える方法を 追加する必要があります 編集ボタンをツールバー項目に追加しましょう

    toolbarモディファイアを使用して

    SwiftUIビューを ツールバー項目に加えます その中に編集モードを自動で切り替えられる 編集ボタンを追加します iOSでのみ表示したいので ボタン周辺に“if os(iOS)”を追加し

    ツールバーにのみ追加されるようにします

    Listの編集モードを切り替えましょう

    各データ行には編集コントロールがありますが 下部の静的要素にはありません SwiftUIは編集コントロールを 必要な行だけに自動的に表示します

    アイテムの並べ替えや タップによる削除ができます

    新たにサンドイッチを追加する ボタンを作るには toolbarモディファイアに別のビューを追加します このビューでは “add”というLabelが付いたボタンと

    makeSandwichメソッドを呼び出す アクションを作ります

    ボタンをタップすると 新しいサンドイッチが現れました

    追加内容をざっと確認しましょう まず編集操作をListに追加する方法です

    これらのモディファイアと

    データを変更する関数のみ使用しました

    サンドイッチタイプを 特定する方法を覚えていますか? ForEachはコレクションへの変更を監視し 正しい挿入と削除を合成するため Listに行を加除する指示は不要です つまりデータソースの 不整合の例外がなくなりました

    toolbarモディファイアを使用し

    Listを編集して新項目を加える ツールバー項目も追加しました 最小限のビューコードで この洗練されたList UIを作成できます

    Appはすぐに構築できましたが 製品として必要な作業は まだあるとお考えでしょう Dynamic Typeやダークモード ローカリゼーションなどへの対応です SwiftUIを使えば それらも自動的に行えます プレビューを使用して簡単にテストできます プレビューを見てみましょう “プレビュープラス”ボタンをクリックし 2つ目のプレビューを追加します

    次に“検査”ボタンをクリックして 新しいプレビューを設定

    Dynamic Typeのサイズを より大きな値にします

    見栄えが良くなりましたね

    このプレビューの変更で 追加されたコードを見てみます

    Xcodeはプレビューの環境で 値を設定するモディファイアを追加しました プレビュー環境では ビューに関するコンテキスト情報を設定でき 情報はビューの階層を流れ すべてのビューの側面を変更します ビューにカスケード変更を加えるのに便利です

    別のプレビューインスタンスを追加しましょう

    今回はプレビューインスペクタで

    カラースキームを“暗い”に設定

    すべてが自動的に表示されます 最後に 他言語による Appの動作を見てみましょう 英語の文字列ファイルを Appにドロップします

    これらのファイルのローカライズを Xcodeに指示します

    次にプロジェクトファイルに移動し

    ローカリゼーションを アラビア語にインポートします

    ビューコードに戻り 再度プレビューを追加します

    環境のレイアウト方向を

    右から左に設定します

    既にすべてが機能していますね

    最後にロカールの設定を

    アラビア語に

    ローカライズされました 私たちのコードが優れているのは

    これらの機能への対応が簡単な点です ローカライズを可能にする 文字列のマークアップも不要でした 文字列リテラルを使用して テキストを自動的に推測しローカライズします

    テキストはモデル値と同様に そのまま使用する必要があります 文字列補間を使用したローカライズも可能です ぜひSwiftUIをご活用ください これらの動作は無料で入手でき より迅速に 優れたAppを構築できます

    構築した際は今一度見直し 正しく機能するかを確認しましょう ダークモードバージョンを使用し Appをライブにします 今回はデバイス上で実行します

    iPhoneが接続されているので このボタンをクリックして

    ビューを送信しプレビューします

    サンドイッチのListです タップすると詳細が表示されます

    タップでズームすると transitionのある “スパイシーな”バナーが非表示になります このアニメーションは常にインタラクティブです

    Listの編集もできます

    上に移動します

    場違いなホットドッグは削除して

    新しいサンドイッチを追加します

    今回のAppについて 最後に1つ補足しておきます App全体を構築し 高性能な動作のテストを Appを一切使わずに実施した点です Xcodeプレビューにより Appの表示 編集 デバッグが未だかつてなく高速に行えます ご視聴 感謝します SwiftUIをお楽しみください

    • 17:18 - Views are lightweight

      struct SandwichDetail: View {
          let sandwich: Sandwich
      
          var body: some View {
              Image(sandwich.imageName)
                  .resizable()
                  .aspectRatio(contentMode: .fit)
          }
      }
    • 18:30 - Views are composed

      struct SandwichDetail: View {
          let sandwich: Sandwich
      
          var body: some View {
              Image(sandwich.imageName)
                  .resizable()
                  .aspectRatio(contentMode: .fit)
          }
      }
    • 19:52 - View are dynamic

      struct SandwichDetail: View {
          let sandwich: Sandwich
          @State private var zoomed = false
      
          var body: some View {
              Image(sandwich.imageName)
                  .resizable()
                  .aspectRatio(contentMode: zoomed ? .fill : .fit)
                  .onTapGesture { zoomed.toggle() }
          }
      }
    • 21:40 - Where is truth?

      struct SandwichDetail: View {
          let sandwich: Sandwich
          @State private var zoomed = false
      
          var body: some View {
              Image(sandwich.imageName)
                  .resizable()
                  .aspectRatio(contentMode: zoomed ? .fill : .fit)
                  .onTapGesture { zoomed.toggle() }
          }
      }

Developer Footer

  • ビデオ
  • WWDC20
  • SwiftUIのご紹介
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン