ハイライト
iPadOS 15 では、iPad アプリの生産性を向上させるための 3 つのコア機能が導入されています。Prominent Scenes によりモーダル中心のインタラクションが可能になり、UIMenuBuilder によりキーボード ショートカットに分類され検索可能なメニュー インターフェイスが可能になり、ポインター アクセサリとバンド選択によりポインター操作に複数選択機能と視覚的なプロンプト機能が追加されます。
主な内容
iPad ユーザーは、複雑なタスクを完了するためにデバイスにますます依存しています。ただし、マルチウィンドウ管理、キーボード ショートカットの検出、ポインタの操作などのデスクトップ レベルの機能は、iPad では完全ではありません。iPadOS 15 はこれら 3 つの方向から同時に動作します。
著名なシーン: フォーカス モードの新しいウィンドウ
(02:54)
iPadOS 13ではマルチウィンドウが導入されましたが、すべてのウィンドウが横長になります。iPadOS 15 新しいprominent新しいウィンドウがモーダルに表示され、背景ウィンドウが自動的に暗く表示される表示スタイル。これは、1 つのドキュメントまたは電子メールに集中する必要があるシナリオに適しています。
使用prominentシーンは 3 つの条件を満たしている必要があります。コンテンツが独立していて完全であること、[完了] または [閉じる] ボタンがあること、特定のコンテンツ (単一のドキュメントなど) に焦点を当てていることです。システムが提供するのは、UIWindowScene.ActivationActionを使用すると、開発者はわずか数行のコードで「新しいウィンドウで開く」オプションをコンテキスト メニューに追加できます。
キーボード ショートカット メニュー: 非表示から検出可能へ
(14:11)
iPadOS 15では、Commandキーを長押しすると、新しいショートカットメニューが表示されます。メニューはファイル、編集、表示などのカテゴリごとに整理されており、検索をサポートしており、直接クリックしてトリガーすることもできます。これは Mac Catalyst と同じメニュー バーを共有しますUIMenuBuilder API。
主な変更点: 以前に渡されたUIResponder.keyCommandsまたはaddKeyCommand宣言されたショートカット キーは、未分類の領域に表示されます。iPadOS 15ではすべてのショートカットキーを渡す必要がありますbuildMenu(with:)メイン メニュー システムに登録して、完全な分類と検索エクスペリエンスを取得します。
ポインタの機能強化: バンドの選択とアクセサリ
(26:42)
iPadOS 15 は Mac からバンド選択インタラクションを借用しています。複数選択のサポートUICollectionViewオンにすると、クリックしてドラッグすると選択範囲の四角形が自動的に引き出され、枠で囲まれたセルが選択されます。Shift選択範囲を追加するキー、Commandキーを押して選択状態を切り替えます。
ポインター アクセサリーも新しい機能です。開発者は、矢印やプラス記号などの視覚的なキューをポインタに付加して、ビューをドラッグしたり、特定の操作を実行したりできることをユーザーに伝えることができます。アクセサリはポインタのスタイルとは独立しており、リフトやハイライトなどの効果と組み合わせて使用できます。
##詳細
「新しいウィンドウで開く」アクションを作成する
(04:56)
let newSceneAction = UIWindowScene.ActivationAction { _ in
let userActivity = NSUserActivity(activityType: "com.myapp.detailscene")
return UIWindowScene.ActivationConfiguration(userActivity: userActivity)
}
キーポイント:
UIWindowScene.ActivationActionはいUIActionのサブクラスは、メニュー、ボタン、ナビゲーション バーのボタンで直接使用できます。- クロージャリターン
UIWindowScene.ActivationConfiguration、これには、NSUserActivity新しいシーンの内容を表します - iPad および Mac Catalyst では「新しいウィンドウで開く」を表示、iPhone では自動非表示
iPhone に代替動作を提供する必要がある場合は、次のように渡すことができます。alternateパラメータ:
let alternateAction = UIAction(title: "Show Details", image: nil) { _ in
// iPhone 上的替代行为
}
let newSceneAction = UIWindowScene.ActivationAction(
alternate: alternateAction
) { _ in
let userActivity = NSUserActivity(activityType: "com.myapp.detailscene")
return UIWindowScene.ActivationConfiguration(userActivity: userActivity)
}
コレクション ビューのジェスチャにより新しいシーンが開きます
(06:58)
func collectionView(_ collectionView: UICollectionView,
sceneActivationConfigurationForItemAt indexPath: IndexPath,
point: CGPoint) -> UIWindowScene.ActivationConfiguration? {
guard let itemActivity = itemUserActivity(at: indexPath) else {
return nil
}
return UIWindowScene.ActivationConfiguration(userActivity: itemActivity)
}
キーポイント:
- 成し遂げる
UICollectionViewDelegateピンチして展開するジェスチャをサポートする新しい方法 - 戻る
nilセルが新しいウィンドウで開くことをサポートしていないことを示します - でのみ使用できます
prominentスタイルシーン表示
カスタムシーントランジションプレビュー
(08:53)
let itemActivity = NSUserActivity(activityType: "com.myapp.detailscene")
let configuration = UIWindowScene.ActivationConfiguration(userActivity: itemActivity)
if let cell = collectionView.cellForItem(at: indexPath) as? ThumbnailCell {
configuration.preview = UITargetedPreview(view: cell.thumbnailView)
}
return configuration
キーポイント:
- デフォルトの遷移はセル全体から始まり、によって設定されます。
previewセルのサブビューからトランジションを開始できます UITargetedPreviewトランジションアニメーションの開始点ビューを指定します- これにより、アニメーションがコンテンツの関係をより正確に反映できるようになります。
シーン状態の保存と復元
(10:18)
func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? {
guard let viewController = self.window?.rootViewController as? EditorViewController else {
return nil
}
let stateActivity = NSUserActivity(activityType: "com.myapp.editorstate")
stateActivity.addUserInfoEntries(from: [
"content": viewController.textField.text ?? "",
"interactionState": viewController.textField.interactionState ?? NSNull()
])
return stateActivity
}
キーポイント:
interactionStateこれは iPadOS 15 の新しい属性であり、カーソル位置、スクロール位置、ファーストレスポンダのステータスなどのインタラクティブな情報が含まれます。- 最初にコンテンツを復元する必要があります。その後、インタラクティブな状態を復元できます。
- iPadOS 15の新機能
scene(_:restoreInteractionState:)デリゲート メソッド。ストーリーボードが読み込まれた後、初めてフォアグラウンドに入る前に呼び出されます。
非同期リカバリのステータス:
func scene(_ scene: UIScene, restoreInteractionState stateRestorationActivity: NSUserActivity) {
guard let viewController = window?.rootViewController as? EditorViewController else { return }
scene.extendStateRestoration()
loadContentAsync { result in
viewController.textField.text = result.content
scene.completeStateRestoration()
}
}
キーポイント:
extendStateRestoration()リカバリ時間の延長をリクエストすると、起動イメージが表示されたままになります- リカバリの完了後に呼び出す必要があります
completeStateRestoration()そうでない場合、システムはアプリを強制的に閉じます。 - ネットワークリクエストなど、長時間実行される可能性のあるタスクには適していません。
メインメニューをカスタマイズする
(17:15)
override func buildMenu(with builder: UIMenuBuilder) {
super.buildMenu(with: builder)
guard builder.system == .main else { return }
let tabMenu = UIMenu(options: .displayInline, children: [
UIKeyCommand(title: "New Tab",
action: #selector(newTab(_:)),
input: "t",
modifierFlags: .command),
UIKeyCommand(title: "Close Tab",
action: #selector(closeTab(_:)),
input: "w",
modifierFlags: .command)
])
builder.insertChild(tabMenu, atStartOfMenu: .file)
let bookmarksMenu = UIMenu(title: "Bookmarks", children: [...])
builder.insertSibling(bookmarksMenu, afterMenu: .view)
}
キーポイント:
- 存在する
UIApplicationDelegate中程度の書き換えbuildMenu(with:) builder.system == .mainこれはメインメニューを変更する場合にのみ実行してください。UIMenu.Identifierシステムメニューの識別子定数を提供します- 各メニュー要素には一意の識別子が必要です。ショートカット キーの組み合わせを繰り返すと挿入が失敗し、コンソール ログが出力されます。
ショートカット キーの使用可能性を動的に制御する
(22:38)
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(closeTab(_:)) {
return !openTabs.isEmpty
}
return super.canPerformAction(action, withSender: sender)
}
override func validate(_ command: UICommand) {
if command.action == #selector(toggleBookmark(_:)) {
command.title = currentTab.isInBookmarks
? "Remove from Bookmarks"
: "Add to Bookmarks"
} else {
super.validate(command)
}
}
キーポイント:
canPerformActionショートカットキーが実行可能かどうかを判断してリターンfalse次の場合、ショートカット キーがメニューに非表示になります。validateショートカット キーがトリガーされる前に呼び出され、タイトルやアイコンなどの外観を動的に変更できます。- 両方のメソッドを呼び出す必要があります
super明らかになったケースを処理する
バンド選択 複数選択のインタラクション
(28:47)
let selectionInteraction = UIBandSelectionInteraction { [weak self] interaction in
guard let self = self else { return }
if interaction.state == .selecting {
self.selectItemsInRect(interaction.selectionRect)
} else if interaction.state == .ended {
self.finalizeSelection()
}
}
view.addInteraction(selectionInteraction)
キーポイント:
UIBandSelectionInteractionカスタム ビューに適しており、UICollectionView は自動的にサポートしますselectionRect現在の選択ボックスの長方形の領域ですinitialModifierFlagsドラッグ開始時に押された修飾キー (Shift、Command など) を提供します。
Pointer Accessories
(33:27)
func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? {
let preview = UITargetedPreview(view: self)
let style = UIPointerStyle(effect: .lift(preview))
if #available(iOS 15.0, *) {
style.accessories = [
.arrow(.left),
.arrow(.right)
]
}
return style
}
キーポイント:
accessoriesiOS 15の新機能UIPointerStyle財産.arrow(.left)そして.arrow(.right)これはシステム定義済みの矢印アクセサリです。- アクセサリの位置と角度をカスタマイズできます。
UIPointerAccessory.Position(offset: 23.0, angle: .pi * 1.25)
重要ポイント
1. ドキュメント アプリに Prominent Scene サポートを追加
アプリがドキュメント、電子メール、メモなどを処理する場合は、ユーザーが個々のアイテムを新しいウィンドウで開くことができるようにします。これにより、マルチタスクの効率が直接的に向上します。
実装アイデア: コンテンツ項目ごとに作成NSUserActivity、コンテキストメニューに追加しますUIWindowScene.ActivationAction。設定activationConditionsシステムがリクエストを正しくルーティングしていることを確認します。
2. キーボード ショートカットをメイン メニュー システムに整理します。
すべての既存のコードを監査するkeyCommands属性とaddKeyCommand電話をかける、移行するbuildMenu(with:)。これにより、iPad と Mac の両方でショートカット キーに統一された検出エクスペリエンスが提供されます。
実装アイデア:機能(ファイル、編集、表示など)ごとに分類し、適切に設定するdiscoverabilityTitle、ショートカット キーの競合を処理します (たとえば、Command-I が斜体のショートカット キーと競合する場合は、代わりに Control-Command-I を使用します)。
3. カスタム ビューにバンド選択を実装する
アプリにキャンバスまたはグリッド状のレイアウトがある場合、ユーザーは複数の項目を選択する必要がある場合があります。UIBandSelectionInteractionこれを簡単にしましょう。
実装アイデア: 作成するUIBandSelectionInteraction、によるとinteraction.stateそしてselectionRect選択ステータスを更新します。組み合わせるinitialModifierFlags選択を追加する Shift と選択を切り替えるコマンドをサポートします。
4. ポインター アクセサリを使用して、ドラッグ可能なビューを表示する
ポインタがドラッグ可能なビュー上にあると、ドラッグの方向を示す矢印アクセサリが表示されます。これは、単純なポインタの形状変更よりも直感的です。
実装アイデア: でUIPointerInteractionのstyleForメソッド内でビューステートに応じてバンドを返しますaccessoriesのUIPointerStyle。組み合わせるlatchingAxesドラッグ時にポインタ効果がビューに追従するようにします。
5. シーン状態の回復を改善する
ユーザーは、アプリを切り替えたり、デバイスを再起動したりすると、以前の動作状態に戻ることを期待します。コンテンツの状態とインタラクション状態 (カーソル位置、スクロール位置) を保存します。
実装アイデア: でstateRestorationActivity(for:)コンテンツを保存し、interactionState。存在するscene(_:restoreInteractionState:)回復。リカバリに非同期ロードが必要な場合は、次を使用します。extendStateRestoration()そしてcompleteStateRestoration()。
関連セッション
- UIKit の新機能 — ボタン、リスト、SF シンボルなどを含む、iOS 15 の UIKit フレームワークの包括的なアップデート
- iPad キーボード ナビゲーションにフォーカス — iPad キーボード ナビゲーションのフォーカス システムの詳細な説明
- UIKit ボタン システムの紹介 — iOS 15 の完全に新しい UIButton.Configuration API
- iPadOS ポインター用のビルド — iPadOS ポインター インタラクション API の詳細な説明
コメント
GitHub Issues · utterances