View in English

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

クイックリンク

5 クイックリンク

ビデオ

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

WWDC22に戻る

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

  • 概要
  • トランスクリプト
  • コード
  • iPadのSwiftUI:ツールバーやタイトルなどを追加する

    SwiftUIでiPad Appのツールバーを調整する用意はよろしいでしょうか。iPadのスペースを活用できるようツールバーを構造化する方法や、ユーザーが自身の生産性を最大限に高められるようにする方法を紹介します。また、カスタマイズ化や、ドキュメントの表示方法などに関する最新情報についても解説します。 これは、2部構成シリーズの後半セッションになります。この動画を最大限に活用するには、「iPadのSwiftUI:インターフェイスをオーガナイズする」からご覧ください。

    リソース

    • Configure your apps navigation titles
    • ControlGroup
    • ShareLink
    • ToolbarItem
    • ToolbarRole
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC23

    • より優れたドキュメントベースのアプリを構築

    WWDC22

    • iPad Appデザインの最新情報
    • iPadのSwiftUI:インターフェイスをオーガナイズする
    • SwiftUI Appに複数のウインドウを追加する
    • SwiftUIの最新情報
  • このビデオを検索

    SwiftUIチームのエンジニア Harryです SwiftUI on iPadシリーズの 第2部へようこそ 第1部ではRajが リストと表や セレクションやSplit Viewで iPadの大きいスクリーンと インプットデバイスを使い Appを向上させる方法を お話ししました ご覧でないなら そちらから始めることを お勧めします Rajが素晴らしい「Places」Appを 作成しました そこに機能を足そうと 思います そこで このセッションでは 僕の大好きな ツールバーに焦点を当てます SwiftUIはToolbar APIで さまざまなシステムバーを設計でき iOSのナビゲーションバーや 下部のバー macOSのウインドウ ツールバーがその例です ツールバーはよく使用する 機能への近道を提供します いいツールバーはユーザーの 生産性を向上します

    ツールバーのことを 考えていましたが PlacesでiOS 16の新しい ツールバー機能を使用できます iPadでどんなことが 可能になるか 僕の作ったものを 少しお見せしましょう

    これがPlaces Appの 完成品です

    新しい機能として左揃えの ナビゲーションタイトルや タイトルメニューに タイトルメニューヘッダ 中央揃えのツールバーがあります Macを使うなら 見慣れた機能である ツールバー カスタマイゼーションは ツールバーを自分のものに 変更することができます これらのMacの強力な機能が iPadにも登場します

    まず最初に Toolbar APIの 向上点をご紹介します そしてタイトルとドキュメントの 新しいAPIをご紹介します では まずはツールバーです すでにiOSでツールバーを 設定された方も多いでしょう 小さいスクリーンを 有効に使うため このようにメニューを 追加したかもしれません

    コードではこうなります

    primaryActionのある ToolbarItemがあります その中にコントロールを コンテンツにした さらなるメニューがあります ではiPadで見てみましょう ご想像通り あまりスペースを 有効に使っていません しかし 嬉しいことに iOS 16では ツールバーはこのような メニューを具体化します オーバーフロー メニューと呼び 有効に使うため ツールバーのコンテンツを 作り直しましょう

    まずToolbarItemを ToolbarItemGroupに変換し メニューを取り除き そのコンテンツを ToolbarItemGroupの コンテンツにします これにより各ツールバーアイテムを グループのビューに挿入します iPadとMacでは これだけで 自動的にオーバーフロー メニューに動かせるのです まだできることが ありますが その前に ツールバーアイテムの プレースメントを考えます プレースメントはツールバー アイテムが表示されるエリアです 違うプレースメントを 同じエリアに配置できます 3つのエリアがある ナビゲーションバーのように 左と中央と右エリアがあります 左と右に通常 コントロールがあります 中央にはAppの ナビゲーションタイトルがあります ではPlacesで見てみましょう

    PlacesではprimaryAction ToolbarItemGroupが iPadとMacの 右エリアにあります primaryActionsは そのスクリーン上での 最も共通的アクションを 示します iOS 16ではsecondaryAction という新しいplacementがあります これらは頻繁に使われる コントロールではないものの 独自のツールバーアイテムを 持つことができます お気に入り追加や編集は Placesでは重要ではないので secondaryActionとします

    secondaryActionはツールバーでは 見えないのがデフォルトです その代わりにオーバーフロー メニューにあります その行動は新しいtoolbarRole 修飾子で変更します

    この修飾子は意味役割を 割り当てることで影響を与え ここではエディタとして ナビゲーションバーに コンテンツ編集用に 最適化するべきだと伝えます ナビゲーションバーは ツールバーアイテムの表示に スペースが要ると解釈し ナビゲーションタイトルを 中央から左エリアに 移動させます これでオーバーフロー メニューに動かす前に secondaryActionを 中央に配置できます コンパクトサイズクラスでは ナビゲーションバーは変わらず 中央でタイトルを 表示し続けます

    secondary actionと toolbar role APIで PlacesはiPadのサイズを 有効に使えるようになります 中央が使えるようになり ツールバーにアイテムを足せます ノイズボタンや 快適レベルボタンや ゴミ箱ボタンなどです しかし足しすぎると ユーザーによっては 扱いにくくなります MacOSではツールバーの カスタマイズをサポートし ユーザーが使用しやすい ツールバーを選べます iPadOSもカスタマイズが できるようになりました macOSの既存のtoolbar customization APIで この機能を適応できます 見てみましょう カスタマイズできるのは ツールバーアイテムだけですので ToolbarItemGroupを ToolbarItemsに分けます 機能的な変化はありません またツールバーの アイテムそれぞれに ユニークな識別子が 必要になりますので それぞれIDを追加します IDはAppを通して一意で 一貫せねばなりません ユーザーがツールバーを カスタマイズする時 SwiftUIは これらのIDを要求し 表示するビューの参照に 使用するからです 最後にツールバー識別子にも IDを足します これでツールバーが カスタマイズできます

    カスタマイズの特徴として ツールバーアイテムは最初 表示させないようにすることもできます これらはカスタム ポップオーバーとして初めて現れ 後にツールバーに追加できます 最初に現れないため 特定のワークフローに便利な アクションに向いています 見てみましょう

    新しいアイテムを目立たせるため 現在のツールバーのアイテムを隠します

    そして ShareLinkのある ツールバーアイテムを足します ShareLinkはTransferable という新しいプロトコルです これらの詳細については 「Transferableの紹介」 セッションご覧ください 設定が済み showsByDefaultを falseとすれば 最初にツールバーに現れません

    ご覧のように共有リンクが カスタマイズポップオーバーに あります そこからツールバーに ドラッグできます いい機能ですよね 共有リンクも設定し ツールバーアイテムの 関係について考えます 共有リンクを ツールバーに移動した後 画像とマップアイテムが 離れてしまいました でもこれらは編集 コントロールですので その関係をツールバーで 確立しようと思います

    iOS 16とmacOS Venturaは ControlGroupを使って この関係をサポートします 見てみましょう 画像とマップの 調整アクションが ツールバーに それぞれあります これらをグループ化するため 同じアイテムに動かします そしてControlGroupとして 囲みます

    これで同じユニットとして ツールバーから動かせます なかなかの機能ですが ControlGroupの新APIで さらに高度なことも可能です ControlGroupに ラベルを提供することで このグループのアイテムは オーバーフローメニューに動く前に 独自の小さいメニューに 畳むことができます ツールバーが 出来上がってきました 最後にもう1つ変更を加えます 新しい場所を足すのは よくある重要なアクションなので そのツールバーアイテムを 足してみます

    そのためにツールバーに 新しいボタンを足します でもこれは最もよくある アクションだと思うので 今回は primaryActionを使用します

    これはiOSとmacOSの 重要で明確な違いです macOSでは修飾子内全部が カスタマイズできますが iPadOSでは secondaryActionだけです ですので右のエリアで レンダリングする新しいボタンは ユーザーによって カスタマイズできません わあ! 情報満杯ですね でもこれだけではありません ナビゲーションタイトルにも 新機能があります メニューやドキュメントもそうです ドキュメントを見てみましょう いろんな種類があります Document group APIに 親しみがあるかもしれません ドキュメントグループには ドキュメントの管理に役立つ たくさんの ビルトイン機能があります ドキュメントグループを使うと これらはすべて無料で行うことができます

    しかしPlacesではドキュメント グループを使用していなくても それぞれの場所が ドキュメントと考えられます 編集できるプロパティがあり Places appで 追加・削除ができ 友達とも共有できます ドキュメントグループベースでない Appで これをどう見せられるか 見てみましょう すでにplace nameを ナビゲーションタイトルに関連させ ツールバーのタイトルを この場所に関連づけています iOS 16では新しいナビゲーション タイトルの修飾子で さらに先へ 行くことができます ナビゲーションタイトルは メニュー表示をサポートできます macOSの「ファイル」メニューのようなものと 考えてください これを作るには ナビゲーションタイトルに アクションを提供します 普通のメニューと同様です タイトルに メニューインジケータが付き メニューにアクションが あることを示唆します それだけではありません 僕のお気に入りは編集可能 タイトルのサポートです ナビゲーションタイトルに バインディングをパスし ツールバーにタイトル編集の サポートを伝えます 唯一ないのは編集を 始める方法だけです タイトルメニューのアクション内で RenameButtonを 使用することができます

    リネームボタンをタップし タイトルを改名します さらに ビューにナビゲーション タイトルを関連づけるように ドキュメントを 関連づけることができます ドキュメントが提供されると プレビュー付きの特別な ヘッダーが表示されます プレビューはドラッグ可能で 共有クイックアクセスがあります これらはナビゲーション ドキュメント修飾子で ナビゲーションドキュメントを ビューに関連付けすることで実現できます transferableに従うタイプか URLを直接 提供することで可能です ここでは今見ている場所を マップで開くURLを提供します URLを提供すればナビゲーション ドキュメント修飾子は macOSのウインドウツールバーの プロキシアイコンも設定します

    これでツールバーの作成から 一息取ることができます 多くの機能を 追加できたでしょ? 早く使いたいですね iPadでのPlaces Appの向上を たくさんカバーしました iPadのツールバーには 多くの新機能があります オーバーフローメニューや カスタマイぜーションがその例です secondaryAction配置 とcustomization APIで iPadとMacの大きい スペースを有効に使えます

    タイトルもまた新しい機能が 追加されました ナビゲーションタイトルや タイトルメニューの作成などです ナビゲーションドキュメント 修飾子を使いましょう SwiftUI on iPadシリーズを お楽しみいただけましたか? 表や選択できるツールバーなどで iPad Appのレベルを さらに上げましょう ありがとうございました

    • 0:01 - Explicit More Menu

      PlaceDetailContent(place: $place)
          .toolbar {
              ToolbarItem(placement: .primaryAction) {
                  Menu {
                      FavoriteToggle(place: $place)
                      AdjustImageButton(place: $place)
                      AdjustMapButton(place: $place)
                  } label: {
                      Label(
                          "More", 
                          systemImage: "ellipsis.circle")
                  }
              }
          }
    • 0:02 - Menu in ToolbarItemGroup

      PlaceDetailContent(place: $place)
          .toolbar {
              ToolbarItemGroup(placement: .primaryAction) {
                  Menu {
                      FavoriteToggle(place: $place)
                      AdjustImageButton(place: $place)
                      AdjustMapButton(place: $place)
                  } label: {
                      Label("More", systemImage: "ellipsis.circle")
                  }
              }
          }
    • 0:03 - ToolbarItemGroup with Menu Content

      PlaceDetailContent(place: $place)
          .toolbar {
              ToolbarItemGroup(placement: .primaryAction) {
                  FavoriteToggle(place: $place)
                  AdjustImageButton(place: $place)
                  AdjustMapButton(place: $place)
              }
          }
    • 0:04 - Secondary Action ToolbarItemGroup

      PlaceDetailContent(place: $place)
          .toolbar {
              ToolbarItemGroup(placement: .secondaryAction) {
                  FavoriteToggle(place: $place)
                  AdjustImageButton(place: $place)
                  AdjustMapButton(place: $place)
              }
          }
    • 0:05 - Toolbar Role

      PlaceDetailContent(place: $place)
          .toolbar {
              ToolbarItemGroup(placement: .secondaryAction) {
                  FavoriteToggle(place: $place)
                  AdjustImageButton(place: $place)
                  AdjustMapButton(place: $place)
              }
          }
          .toolbarRole(.editor)
    • 0:06 - Individual ToolbarItems

      PlaceDetailContent(place: $place)
          .toolbar {
              ToolbarItem(placement: .secondaryAction) {
                  FavoriteToggle(place: $place)
              }
              ToolbarItem(placement: .secondaryAction) {
                  AdjustImageButton(place: $place)
              }
              ToolbarItem(placement: .secondaryAction) {
                  AdjustMapButton(place: $place)
              }
          }
          .toolbarRole(.editor)
    • 0:07 - Customizable ToolbarItems

      PlaceDetailContent(place: $place)
          .toolbar(id: "place") {
              ToolbarItem(id: "favorite", placement: .secondaryAction) {
                  FavoriteToggle(place: $place)
              }
              ToolbarItem(id: "image", placement: .secondaryAction) {
                  AdjustImageButton(place: $place)
              }
              ToolbarItem(id: "map", placement: .secondaryAction) {
                  AdjustMapButton(place: $place)
              }
          }
          .toolbarRole(.editor)
    • 0:08 - ShareLink ToolbarItem

      PlaceDetailContent(place: $place)
          .toolbar(id: "place") {
              ToolbarItem(id: "favorite", placement: .secondaryAction) {
                  FavoriteToggle(place: $place)
              }
              ToolbarItem(id: "image", placement: .secondaryAction) {
                  AdjustImageButton(place: $place)
              }
              ToolbarItem(id: "map", placement: .secondaryAction) {
                  AdjustMapButton(place: $place)
              }
              ToolbarItem(id: "share", placement: .secondaryAction) {
                  ShareLink(item: place)
              }
          }
          .toolbarRole(.editor)
    • 0:09 - Non-default ShareLink ToolbarItem

      PlaceDetailContent(place: $place)
          .toolbar(id: "place") {
              ToolbarItem(id: "favorite", placement: .secondaryAction) {
                  FavoriteToggle(place: $place)
              }
              ToolbarItem(id: "image", placement: .secondaryAction) {
                  AdjustImageButton(place: $place)
              }
              ToolbarItem(id: "map", placement: .secondaryAction) {
                  AdjustMapButton(place: $place)
              }
              ToolbarItem(id: "share", placement: .secondaryAction, showsByDefault: false) {
                  ShareLink(item: place)
              }
          }
          .toolbarRole(.editor)
    • 0:10 - ControlGroup in ToolbarItem

      PlaceDetailContent(place: $place)
          .toolbar(id: "place") {
              ToolbarItem(id: "favorite", placement: .secondaryAction) {
                  FavoriteToggle(place: $place)
              }
              ToolbarItem(id: "image", placement: .secondaryAction) {
                  ControlGroup {
                      AdjustImageButton(place: $place)
                      AdjustMapButton(place: $place)
                  }
              }
              ToolbarItem(id: "share", placement: .secondaryAction, showsByDefault: false) {
                  ShareLink(item: place)
              }
          }
          .toolbarRole(.editor)
    • 0:11 - ControlGroup in ToolbarItem with Label

      PlaceDetailContent(place: $place)
          .toolbar(id: "place") {
              ToolbarItem(id: "favorite", placement: .secondaryAction) {
                  FavoriteToggle(place: $place)
              }
              ToolbarItem(id: "image", placement: .secondaryAction) {
                  ControlGroup {
                      AdjustImageButton(place: $place)
                      AdjustMapButton(place: $place)
                  } label: {
                      Label("Edits", systemImage: "wand.and.stars")
                  }
              }
          }
          .toolbarRole(.editor)
    • 0:12 - NewButton ToolbarItem

      PlaceDetailContent(place: $place)
          .toolbar(id: "place") {
              ToolbarItem(id: "new", placement: .primaryAction) {
                  NewButton()
              }
              ToolbarItem(id: "favorite", placement: .secondaryAction) {
                  FavoriteToggle(place: $place)
              }
              ToolbarItem(id: "image", placement: .secondaryAction) {
                  ControlGroup {
                      AdjustImageButton(place: $place)
                      AdjustMapButton(place: $place)
                  } label: {
                      Label("Edits", systemImage: "wand.and.stars")
                  }
              }
              ToolbarItem(id: "share", placement: .secondaryAction, showsByDefault: false) {
                  ShareLink(item: place)
              }
          }
          .toolbarRole(.editor)
    • 0:13 - Navigation Title

      PlaceDetailContent(place: $place)
          // toolbar customizations ...
          .navigationTitle(place.name)
    • 0:14 - Navigation Title with Menu

      PlaceDetailContent(place: $place)
          // toolbar customizations ...
          .navigationTitle(place.name) {
              MyPrintButton()
          }
    • 0:15 - Editable Navigation Title with Menu

      PlaceDetailContent(place: $place)
          // toolbar customizations ...
          .navigationTitle($place.name) {
              MyPrintButton()
          }
    • 0:16 - Editable Navigation Title with RenameButton

      PlaceDetailContent(place: $place)
          // toolbar customizations ...
          .navigationTitle($place.name) {
              MyPrintButton()
              RenameButton()
          }
    • 0:17 - Navigation Document

      PlaceDetailContent(place: $place)
          // toolbar customizations ...
          .navigationTitle($place.name) {
              MyPrintButton()
              RenameButton()
          }
          .navigationDocument(place.url)

Developer Footer

  • ビデオ
  • WWDC22
  • iPadの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.
    利用規約 プライバシーポリシー 契約とガイドライン