SwiftUIにおけるアクセシビリティ – WWDC2019

Session概要

アプリをアクセシビリティ対応にすることが重要であるのと同様に、素晴らしいアクセシビリティ体験を設計することも重要です。
このセッションでは、優れた体験には何が必要か、そして理解しやすく操作しやすいアプリを作成する方法について説明します。
SwiftUIでは、自動的にアプリにアクセシビリティを組み込むことができます。アクセシビリティ対応の画像やコントロールなど、多くの機能が自動的に実装される様子についてご確認ください。新しいSwiftUIのAccessibility APIを使用して、どこに補助的なアクセシビリティ情報を追加できるかについても紹介します。このAPIを活用すると、ラベル、値、ヒントといった要素に情報を追加することができます https://developer.apple.com/videos/play/wwdc2019/238/

アクセシビリティの紹介

アクセシビリティの機能

アクセシビリティとは何か

  • 障がいのある人でもアプリを存分に楽しめるようにする機能
    • 例えば、VoiceOverは視覚に障がいのある人もデバイスの操作が可能になります
      • iOSではジェスチャー、Macではキーボードを利用して操作することができる
  • Mac, iPhone, Watch, HomePodなど多くのデバイスで支援機能を組み込んでいる

アクセシビリティの新機能

  • Voice Control
    • 音声によるナビゲーション、インタラクション
  • フルキーボードアクセス
    • キーボードであらゆる操作が可能。画面移動やコマンド指示など

アクセシビリティUI

  • アプリの各Viewがアクセシビリティ要素となり、ラベル(AccessibilityLable)やアクションを持つ
    • アクションはDefaultのアクションとカスタマイズ可能なアクションがある

アクセシビリティUIを実装する上で重要なポイント

  1. アクセシビリティ要素はわかりやすくすること
    • 理解しやすいラベルと値情報の記述が必要
  2. 操作可能
    • 適切なDefaultアクションとカスタムアクションを意味する
  3. ナビゲーション
    • アクセシビリティの配列とグループ化でアクセシビリティ機能の利便性は決まる

SwiftUI活用時における自動的なアクセシビリティ実装

  • SwiftUIはアクセシビリティAPIを備えている
    • 例えば、アクセシビリティ要素の値変更時における通知
  • SwiftUIではUIViewと同様にアクセシビリティ要素も自動で生成する
    • 下記の例だと、TextとButtonにアクセシビリティ要素が生成されている

SwiftUIでのアクセシビリティ要素の自動生成
アクセシビリティ要素の変更時における通知

カスタムUIにおけるアクセシビリティ

下記実装を用いてカスタムのUIを実装しても、アクセシビリティ要素は自動生成され、デザインやレイアウトの実装に集中可能
// With SwiftUI, you can easily customize button drawing

struct CustomButtonStyle : ButtonStyle {
func body(configuration: Button<Label>, isPressed: Bool)
 -> some View
 {
 configuration.label
 .font(size: 18)
 .foregroundColor(isPressed ? .black : .white)
 .padding(8)
 .background(
 RoundedRectangle(cornerRadius: 5)
 .fill(isPressed ? Color.red : Color.blue)
 )
 }
}
Customのstyleを用いたButtonの実装

画像への直感的なアクセシビリティの提供

  • Imageにlabelを付与することでアクセシビリティラベルを設定可能
  • 画像が単に装飾の場合は、decorativeで定義することで読み上げはされない

Imageへのアクセシビリティラベルの付与 

Pickerにおけるcontrol labelの実装サンプル

// Control labels for accessibility in SwiftUI
static let voices = [ "Alex", "Fred", "Victoria" ]
@State var selectedVoice = Self.voices.first!

var body: some View {
  Picker(selection: $selectedVoice,
   label: Text("System Voice")) {
     ForEach(Self.voices.identified(by: \.self)) {
      Text(verbatim: $0)
     }
   }
}
picker controlにおけるアクセシビリティラベルの紐付け

SwiftUIにおけるAccessibility APIの説明

  • アプリがユーザに求められるもの
    • 理解しやすさ(わかりやすさ)
      • そのための文字列の情報は十分か?
    • インタラクティブ
      • 設定したアクションはシンプルか?
    • ナビゲーション
      • 素早いナビゲーションか?

traitを用いてbuttonの状態を付与する
アクセシビリティラベルとアクションの設定

理解しやすいアクセシビリティの実装

  • スライダーなどのUIコンポーネントにも適切な情報を付与する

understandable accessibility label

操作しやすいアクセシビリティの実装

interactable accessesibility action

ナビゲートしやすいアクセシビリティの実装

  • アプリの画面レイアウトに合わせて適切なheaderを設定する
    • 下記の例では、アプリは大きく3つの機能に分かれているので3分割している
  • VoiceOverローターを用いて、素早いナビゲーションが可能となる

アクセシビリティツリーについて

  • アクセシビリティツリーは実装したUIコンポーネントの階層を表しており、アクセシビリティの対象は上位階層からたどってアクセスする
    • そのため、アクセシビリティの対象を明確にするにはアクセシビリティツリーを意識した実装をする
  • sortPriorityを用いて、UI要素の読み上げにおける優先度をソートする
    • ZStackを用いると画面の表示と読み上げの順序がマッチしない可能性があるため

combineでまとめる前のアクセシビリティツリー
反復して表示される場合,読み上げ要素が複数あり操作の対象がわからない状態
combineを使用した後のアクセシビリティツリー
要素をまとめることで読み上げ対象を明確にする

アクセシビリティ機能を満たしているか確認する

  • 実際にアクセシビリティ機能を使用する
    • VoiceOver
    • フルキーボードアクセス
  • Accessibility Inspectorを使用する
最新情報をチェックしよう!