ハイライト
iOS のフル キーボード アクセスにより、ユーザーはキーボードのみを使用して iPhone および iPad を操作できるようになり、開発者はカスタム アクション、キーボード ショートカット、対話性マーカー、入力タグ、アクセシビリティ パスを通じてアプリをキーボード ユーザーに適応させることができます。
主要内容
一部のユーザーは画面を安定してタッチできない場合があります。指の可動範囲が限られていたり、手が震えたり、細かい操作がしにくいため、タップや長押し、ドラッグする際に負担がかかります。
iOSではすでにAssistiveTouch(補助タッチ)、Switch Control(スイッチ制御)、Voice Control(音声制御)が提供されています。フル キーボード アクセスにより、別の入力方法が追加されます。ユーザーは外部キーボードのみを使用して、システム ナビゲーション、要素の選択、操作メニュー、検索およびジェスチャ モードを完了できます。
これは iPad にとって特に重要です。ユーザーは、矢印キーを使用して移動、スペースキーを使用してアクティブ化、Tab キーを使用して別の領域に入ることができ、Tab-Z を使用してアクション メニューを開き、Tab-F を使用してインターフェイス要素を見つけることができます。キーボードが補助入力から完全な入力パスに変わります。
開発者が遭遇した問題は詳細に表示されます。ボタンは Tab で選択できますが、Space を押しても反応しません。カードは長押ししてカードを最上部に維持することをサポートしていますが、キーボード ユーザーはこのアクションを見つけることができません。設定ボタンには歯車アイコンしかなく、ユーザーは「設定」と「設定」のどちらを検索すればよいのかわかりません。
Apple は、このセッションで修復プロセスをデモンストレーションするために、Shape Shuffle と呼ばれる小さなゲームを使用しました。中心となるアプローチは、既存のコントロールのアクセシビリティ情報、つまりこの要素にどのようなアクションがあるか、いつ応答するか、ユーザーがそれを見つけるために使用できる他の単語、およびフォーカス アウトラインの形状を補完することです。
詳細
アクセシビリティカスタムアクションを共通アクションに追加
(07:06) シェイプ シャッフルのカードは、ボードへの追加とピンの追加という 2 つのアクションをサポートします。タッチ ユーザーはダブルクリックまたは長押しでき、キーボード ユーザーには Tab-Z アクション メニューに同じアクションが表示されます。
UIKitへの入り口は、UIAccessibilityCustomAction。アクションをハングアップしますaccessibilityCustomActionsその後、VoiceOver、スイッチ コントロール、フル キーボード アクセスによって検出できるようになります。
// Accessibility custom actions
let addAction = UIAccessibilityCustomAction(
name: gameLocString("add"), image: UIImage(systemName: "plus.square")) { _ in
self.addCard()
return true
}
let pinAction = UIAccessibilityCustomAction(
name: gameLocString("pin"), image: UIImage(systemName: "pin.fill")) { _ in
self.pinCard()
return true
}
cardView.accessibilityCustomActions = [addAction, pinAction]
キーポイント:
UIAccessibilityCustomAction支援技術が呼び出すことができるアクションを定義します。nameローカライズされた文字列を使用すると、アクション メニューにこのテキストが表示されます。imageフル キーボード アクセスには表示されませんが、スイッチ コントロールで使用されます。- クロージャで元のビジネス メソッドを呼び出す
addCard()そしてpinCard()、成功後に戻るtrue。 cardView.accessibilityCustomActions2 つのアクションを現在のカードにバインドします。
キーボード ユーザーにショートカット キーを提供する
(08:39) カスタム アクションは、支援技術ユーザーに適しています。キーボード ショートカットの適用範囲は広く、フル キーボード アクセスをオンにしているユーザーが使用できるほか、通常の外付けキーボードを使用しているユーザーも使用できます。
iOS および iPadOS 15 では、Mac Catalyst 13 のメニュー構築 API が iOS に導入されます。開発者ができることAppDelegateカバーされたbuildMenu(with:)、作成するUIKeyCommandを挿入してから、UIMenuBuilder。
// Keyboard shortcuts
// In AppDelegate.swift
override func buildMenu(with builder: UIMenuBuilder) {
super.buildMenu(with: builder)
guard builder.system == .main else {
return
}
let pinCommand = UIKeyCommand(
title: gameLocString("pin"),
image: UIImage(systemName: "pin.fill"),
action: #selector(GameViewController.pinFocusedCard),
input: "P",
discoverabilityTitle: gameLocString("pin.card")
)
let addCommand = UIKeyCommand(
title: gameLocString("add"),
image: UIImage(systemName: "plus.square"),
action: #selector(GameViewController.addFocusedCard),
input: "A",
discoverabilityTitle: gameLocString("add.card")
)
let identifier = UIMenu.Identifier("gameplay_menu")
let menu = UIMenu(
title: gameLocString("gameplay"),
image: UIImage(systemName: "rectangle.grid.3x2"),
identifier: identifier,
children: [addCommand, pinCommand]
)
builder.insertSibling(menu, afterMenu: .view)
}
キーポイント:
buildMenu(with:)ここでシステム メニューにコマンドが追加されます。guard builder.system == .mainこのロジックはメイン メニューにのみ適用されるように制限してください。UIKeyCommandタイトル、アイコン、セレクター、キーをまとめてバインドします。input: "P"そしてinput: "A"ピン留めと追加のショートカット キーをそれぞれ定義します。discoverabilityTitleCommand を押した後に表示されるショートカット パネルに表示されます。UIMenu両方のコマンドを「ゲームプレイ」メニューにグループ化します。builder.insertSibling(menu, afterMenu: .view)View メニューの後にメニューを挿入します。
フォーカスされたカードがある場合にのみコマンドを有効にします
(09:22) ショートカット キーは永久に使用できるわけではありません。シェイプ シャッフルの追加と固定は、カードが選択された後でのみ意味を持ちます。
UIKit はレスポンダー チェーンを使用して、アクションが実行可能かどうかを判断します。カバーcanPerformAction(_:withSender:)、ショートカット パネルに正しい状態のコマンドのみを表示させることができます。
// Keyboard shortcuts
// In GameViewController.swift
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(addFocusedCard) || action == #selector(pinFocusedCard) {
return self.focusedCard != .none
}
return super.canPerformAction(action, withSender: sender)
}
キーポイント:
canPerformActionセレクターが現在実行可能かどうかを判断します。#selector(addFocusedCard)前の例のショートカット キーの追加に対応します。#selector(pinFocusedCard)ピン留めのショートカットキーに対応します。self.focusedCard != .noneユーザーがカードを選択していることを確認してください。 -その他のアクションはに引き継がれますsuper、システムメニューや他のコントロールへの影響を避けるため。
操作できない要素にフォーカスをスキップさせます
(10:35) 開発者は、VoiceOver を適応させた後、多くのビューをアクセス可能な要素としてマークすることがよくあります。 Shape Shuffle の三角形、色、数字は VoiceOver で読み取る必要があるため、コードが設定されます。isAccessibilityElementそしてaccessibilityLabel。
itemView.isAccessibilityElement = true
itemView.accessibilityLabel = gameLocString(for: item)
キーポイント:
isAccessibilityElement = trueさせてitemViewアクセシビリティ ツリーに入ります。accessibilityLabelVoiceOver が読み上げるテキストを提供します。- フル キーボード アクセスのカーソルは、これらのアクセシビリティ要素にもアクセスできます。
- 要素が読み取りのみ可能で操作できない場合、キーボード ユーザーは、「要素は選択されているが、スペースを押しても何も起こりません」のような誤ったフォーカスに遭遇します。
(11:01) 解決策は、accessibilityRespondsToUserInteraction。そうなったときfalseの場合でも、要素は VoiceOver によって読み取られますが、フル キーボード アクセスやスイッチ コントロールなどのモーション アシスト テクノロジはそれをスキップします。
itemView.accessibilityRespondsToUserInteraction = false
キーポイント:
- この属性は以下でのみ使用できます。
isAccessibilityElementすでにtrueそれは理にかなっています。 - デフォルトでは、システムはアクセス可能な要素がインタラクティブであるかどうかを判断しようとします。
- 要素が VoiceOver 読み上げを提供するが、キーボードまたはスイッチ コントロール フォーカスを受け入れない場合に手動で設定します。
false。 - フルキーボードアクセスのために上書きしないでください
canBecomeFocusedなぜなら、これはフォーカス エンジン全体に影響し、フル キーボード アクセスがオンになっていないタブ ナビゲーションにも影響するからです。
検索機能にさらに入力タグを提供します
(13:41) フル キーボード アクセスには検索機能があります。ユーザーが Tab-F を押した後、テキストを入力してインターフェイス要素にすばやくジャンプできます。
問題はアイコンボタンにあります。設定ボタンの名前は「設定」である場合もあれば、ユーザーが「prefs」、「preferences」、または「gear」と入力する場合もあります。accessibilityUserInputLabels開発者が同じコントロールに入力可能な名前の複数のセットを提供できるようにします。
self.accessibilityUserInputLabels = [
gameLocString("settings"),
gameLocString("prefs"),
gameLocString("preferences"),
gameLocString("gear")
]
キーポイント:
accessibilityUserInputLabels文字列の配列です。- すべての文字列はローカライズされ、インターフェイス言語と一致している必要があります。
- フル キーボード アクセスの検索では、これらの文字列を使用して要素を照合します。
- これらの名前は音声コントロールでも使用され、ユーザーはどちらの名前を話してもコントロールをトリガーできます。
- これは VoiceOver に代わるものではありません
accessibilityLabel。
アクセシビリティ パスによるフォーカス アウトラインの改善
(14:52) フル キーボード アクセスのカーソルは、デフォルトでコントロールを四角形で囲みます。 Shape Shuffle のレベル ボタンは円、三角形、四角形であり、長方形のカーソルは視覚的な形状に適合しません。
accessibilityPath要素の実際の形状をシステムに伝えることができます。この API は VoiceOver でも使用されます。
// Accessibility path
let rect = circleLevelButton.convert(levelButton.bounds, to: nil)
circleLevelButton.accessibilityPath = UIBezierPath(ovalIn: rect)
キーポイント:
convert(_:to:)ボタンの境界を画面座標に変換します。accessibilityPath画面座標は必須です。UIBezierPath(ovalIn:)円形または楕円形のパスを作成します。- 設定後、フル キーボード アクセスのカーソルが丸いボタンにフィットします。
ボタンがUIScrollViewここで、スクロールすると画面座標が変化します。 Appleは補償を推奨していますaccessibilityPathまたはaccessibilityFrame、読み取られるたびに再計算されます。
// If your button is in a scroll view, it’s generally better to
// override accessibilityPath and/or accessibilityFrame
extension CircleButton {
open override var accessibilityPath: UIBezierPath? {
get {
let rect = self.convert(self.bounds, to: nil)
return UIBezierPath(ovalIn: rect)
}
set {
// no-op
}
}
}
キーポイント:
- 拡大
CircleButton、から継承されたオーバーライドUIViewのaccessibilityPath。 - ゲッターは、現在の境界を使用して毎回画面座標を再計算します。
- 戻る
UIBezierPath(ovalIn:)、システムに最新の循環パスを取得させます。 - 外部書き込みによる動的計算結果の破損を防ぐため、セッターを空白のままにしておきます。
重要ポイント
-
対処方法: カード、メール、タスク、写真などのリスト項目にキーボード操作メニューを追加します。 実行する価値がある理由:
UIAccessibilityCustomActionフル キーボード アクセス、VoiceOver、スイッチ コントロールを同時に提供し、ユーザーは画面に触れることなく収集、アーカイブ、削除を実行できます。 開始方法: リスト項目ごとに作成しますUIAccessibilityCustomAction、ビジネス メソッドをアクション クロージャに配置し、それを次のように割り当てます。accessibilityCustomActions。 -
内容: 高頻度操作用に iPad のキーボード ショートカットを設計します。 実行する価値がある理由:
UIKeyCommandフル キーボード アクセスをオンにしているユーザーが、通常のキーボード ユーザーと同じショートカット セットを使用できるようにします。 開始方法:buildMenu(with:)作成年UIKeyCommand、コマンドごとに追加しますdiscoverabilityTitle、使用canPerformAction利用可能なステータスを制御します。 -
対処方法: 「誤ったフォーカス」をクリーンアップします。 実行する価値がある理由: キーボード カーソルが操作できない要素の上にあると、ユーザーはアプリケーションが停止していると誤って認識します。 開始方法: フル キーボード アクセスを開き、Tab キーを使用してインターフェイスを移動します。読み上げにのみ使用される要素を見つけたら、それらを保存します。
isAccessibilityElement、バンドルaccessibilityRespondsToUserInteractionに設定false。 -
対処方法: 複数の検索語セットをアイコン ボタンに追加します。 実行する価値がある理由: ユーザーが検索または音声コントロールを使用するとき、開発者がコントロールに付けた名前を必ずしも知っているとは限りません。 開始方法: 設定、共有、フィルタリング、お気に入りのアイコン ボタンを設定します。
accessibilityUserInputLabels、一般的な同義語と口語名を書きます。 -
内容: カスタム形状コントロールのフォーカスの輪郭を視覚的な形状と一致させます。 実行する価値がある理由:
accessibilityPathこれにより、フル キーボード アクセスと VoiceOver で同じ実際のアウトラインを使用できるようになり、フォーカス位置とビジュアル インターフェイスのずれが軽減されます。 開始方法: を使用しますUIBezierPathコントロールの形状を説明します。静的コントロールは直接設定されますaccessibilityPath、スクロール領域のコントロールはゲッターの動的計算をオーバーライドします。
関連セッション
- SwiftUI アクセシビリティ: 基本を超えて — SwiftUI でのアクセシビリティ プレビュー、アクセシビリティ プレゼンテーション、子要素、フォーカス管理について学びます。
- データが豊富なアプリでの VoiceOver エクスペリエンスを調整する — カスタム コンテンツ API を使用して、複雑なデータ インターフェイスの VoiceOver 読み上げエクスペリエンスを向上させます。
- アプリ内のグラフへのアクセシビリティを実現する — アクセシビリティ対応のデータ セマンティクスとグラフのナビゲーションを提供します。
- iPad のキーボード ナビゲーションに焦点を当てる — iPadOS のキーボード フォーカス システムとタブ ナビゲーションについて深く理解します。
コメント
GitHub Issues · utterances