目次
Session概要
Mac Catalyst アプリをすべてのものにアクセスできるようにし、その改良をiPadアプリに取り込みましょう。優れたアクセシビリティを持つiPadアプリが、Mac Catalystのサポートを追加すると自動的に優れたアクセシビリティを持つMacアプリになる仕組みを紹介します。マウスとキーボードのアクションやアクセシビリティエレメントのグループ化とナビゲーションのサポートによってエクスペリエンスをさらに強化する方法をご覧ください。また、アプリをテストし、あらゆる人にとって真に優れたエクスペリエンスを想像するためのイテレーションを行う新しいAccessibility Inspectorフィーチャの使用方法もご覧ください。 https://developer.apple.com/videos/play/wwdc2020/10117/Mac Catalystでのアクセシビリティ対応
- iOSアプリでアクセシビリティが対応可能である場合、macOSでも自動的に対応できるようになった
キーボードを使用するためにアプリを最適化する方法
- やることは フォーカス行動を改善し、キーボードのショートカットを加える
- Mac利用者の主な入力インタフェースはキーボードであるため、なるべくキーボードでアクセス可能にする
キーボードのフォーカス
- キーボードのフォーカスをチェックする
- どのUI要素が、現在キーボードからの入力を受け付けているのかを特定する
- ユーザがアクセスする全てのUI要素にフォーカスできるか確かめる
- そのために、Mac側でキーボードナビゲーションでコントロール間でフォーカスを移動を設定する
- ユーザのキーボードでの主な操作
- tabキー: コンポーネント間の移動、次へ、前へ
- 矢印キー: UITableView/UICollectionViewでのリストの選択肢変更
- スペースキー: フォーカスされたUIコンポーネントの選択、実行

矢印キーで選択肢を変更可能にする方法
- selectionFollowsFocusをtrueに設定する
- UISplitViewのサイドバーでは、自動的にtrueになる
myTableView.selectionFollowsFocus = true
キーボードのショートカットの追加
- 障害者支援技術を使う人たちは、画面上のUIを見つけることが面倒な場合があるため、キーボードショートカットを追加することで解決する
- キーボードの組み合わせは、他の主要なアプリに合わせるとユーザは慣れているため利用しやすい
- キーボードショートカットを追加するために、AppDelegateにてbuildMenu関数を上書きする
- キーボードショートカットに応答するUIKeyCommandを作る
- キーボードショートカットのアクションを割り当てる
- メニューバーにキーボードショートカットを項目として追加する

extension AppDelegate {
override func buildMenu(with builder: UIMenuBuilder) {
super.buildMenu(with: builder)
let shareCommand = UIKeyCommand(title: NSLocalizedString("Share", comment: ""), // ここのタイトルはメニューバーに表示される
action: #selector(Self.handleShareMenuAction),
input: "I",
modifierFlags: [.command])
let shareMenu = UIMenu(title: "",
identifier: UIMenu.Identifier("com.example.apple-samplecode.RoastedBeans.share"),
options: .displayInline,
children: [shareCommand])
builder.insertChild(shareMenu, atEndOfMenu: .edit)
}
@objc func handleShareMenuAction() {
}
}
障害者支援技術のためのナビゲーション効率の向上方法について
- macOSでは VoiceOverユーザはキーボードを使用するため、iOSのようにタッチスクリーンでの要素間のジャンプができない
- そのため、iOSと同じモデルを使用するためにはすべてのアクセシビリティ要素を確認する必要がある
- 各要素を1つづつアクセスさせるのではなく、関連のある要素毎にグループ化し、目標の要素にアクセスするまでのステップ数を減らす
- このグループ化をアクセシビリティコンテナで行い、要素間の関係性を定義する
- 1つの要素にaccessibilityContainerTypeを設定すると、そこに含まれるアクセシビリティ要素によりよいナビゲーション体験を提供する
- アクセシビリティコンテナはアクセシビリティツリーの1つのノードとなる

VoiceOver等ではこのアクセシビリティツリーの上部からアクセスする



アクセシビリティコンテナとは
- Mac Catalystアプリにとって独立したアクセシビリティ要素
- コンテナ自身にアクセシビリティラベルを設定可能
UIAccessibilityContainerTypeについて
- dataTable
- UIAccessibilityContainerDataTableプロトコルを採用する際に利用
- list
- 順序付けられたコンテンツで、webページやPDFの目次などで利用する
- landmark
- webページとtvOSで使用するコンテナ
- semanticGroup
- iOS上お一般的なコンテナ型
- iOSではVoiceOverユーザが最初にそのコンテナの中の要素にフォーカスした時にアクセシビリティラベルが読まれる
- macOSではVoiceOverがそのコンテナ自身にフォーカスした時にそのラベルが読まれる
コンテナの切り分け方
- 型や機能目的で関連する要素にわける
- UIKitのコンポーネント毎にわける
アクセシビリティコンテナの実装
// UIStackViewをアクセシビリティコンテナとし、
// グループに示すアクセシビリティラベルを設定するサンプル
let stackView = UIStackView()
stackView.axis = .vertical
stackView.translatesAutoresizingMaskIntoConstraints = false
let locationsAvailable = viewModel.locationsAvailable
let titleLabel = UILabel()
titleLabel.font = UIFont.preferredFont(forTextStyle: .body).bold()
titleLabel.text = NSLocalizedString("Availability: ", comment: "")
stackView.addArrangedSubview(titleLabel)
for location in locationsAvailable {
let label = UILabel()
label.font = UIFont.preferredFont(forTextStyle: .body)
label.text = "• " + location
label.accessibilityLabel = location
stackView.addArrangedSubview(label)
}
stackView.accessibilityLabel = String(format: NSLocalizedString("Available at %@ locations", comment: ""), String(locationsAvailable.count))
stackView.accessibilityContainerType = .semanticGroup
Mac Catalystアプリ向けにmacOSでアクセシビリティをテストするためのヒント
- アプリをiOSからMac移行する際、内部からはiOSのアプリだと見なすが、外部ではmacOSプラットフォームでも動いているため、Macのアプリだと考える
- そのため、UIKitからのアクセシビリティAPIで作業する時、CatalystによってiOSのアクセシビリティコードをmacOSへ自動変換する
- Accessibility Inspectorを使用して、Catalystでのアクセシビリティ検査が可能
- command key + control key + up keyでインスペクターは、要素のコンテナをチェック可能
- 追加で、インスペクターはすべての要素のために自動型を伝える。これは、XCUIテストでUI要素がどのように検出可能かが正確にわかるようになった


