iOSアプリのアクセシビリティを向上させるために、必要なこと

主にAndroid、たまにiOSのアプリ開発を担当している髙坂(id:k3n)です。

唐突ですが、この記事をご覧になっている皆様が開発に携わっているアプリは、Accessibleでしょうか。アクセシビリティと一口に言っても、VoiceOverのような視覚に頼らないアプリの操作方法をサポートすることであったり、前景色(文字色など)と背景色とのコントラスト比を十分に持たせて視認しやすい色使いにしたり、ボタンのタッチ領域を十分に広くしてボタン操作を容易にするなど、様々なことが関係してきます。

この記事をご覧になっているということは、少なからずアクセシビリティに対する興味・関心を持っていらっしゃると思います。

弊社には、デザイナ・エンジニアを中心にアクセシビリティに強い関心を持つメンバーがいます。さらに、とてもありがたいことに、会社としてもAccessibleなアプリを作れるということを強みの一つにしていこうよ!ということで、業務の一環として、iOSアプリを開発するにあたってアクセシビリティを向上させるためにはどういったことに心を配れば良いのかについて、調査する機会をいただけました(Androidアプリに関してまとめた記事はこちらです)。

本記事では、iOSアプリを開発するにあたって、アクセシビリティを向上させるために何を考慮し、何が必要となるのかを以下の観点をベースにまとめます。

  • エンジニアは、何を考慮する必要があるのか
  • エンジニアが実装するにあたり、デザイナからどのようなインプットが必要となるのか
  • 適切に実装できていることを、どのように確認するのか

本題に入る前に、アプリのアクセシビリティを向上させる上で念頭においていただきたいことがあります。

障碍を持つ人のためだけに対応するのではない。あらゆる人が、どのような環境でも等しく情報を得られるために対応する。

人は誰しも歳を取ります。歳を重ねる中で、目が見えづらくなったり、細かな作業がしづらくなります。あるいは、直射日光下で画面の照り返しがキツく、画面上に表示された情報を視認することが困難なこともあるでしょう。アクセシビリティを向上させることで、より簡単にアプリを操作するための方法を提供できたり、アプリの利用が厳しい環境下でも快適に利用していただけます。僕たちが作り上げたアプリが、より多くの人たちに利用され、より永く愛されるものとなります。

iOSアプリ開発者であれば一度は目を通されたことがあるかと思いますが、Human Interface GuidelinesAccessibilityにおいて、アプリのアクセシビリティを向上させるために押さえるべきポイントがまとめられています。ここで度々言及されていますが、UIKitが提供するシステムコントロールを用いてアプリを実装すれば、アクセシビリティにまつわる設定(Bold Text、Larger Text、Invert ColorsやIncrease Contrastなど)に自動的に準拠でき、またVoiceOverの動作に必要な情報も備えており適切に読み上げられます。ただし、アクセシビリティを考慮せずアプリを作った場合、VoiceOverで想定とは異なる文言が読み上げられる、とか、フォントサイズを拡大するとレイアウトが崩れてしまう、などといった不具合が発生してしまう可能性があります。質の高いiOSアプリを作る上で、アクセシビリティの考慮は避けて通れません。

Designing your app with accessibility in mind means prioritizing simplicity and perceivability and examining every design decision to ensure that it doesn't exclude users who have different abilities or interact with their devices in different ways.

前置きが長くなりました。ここからは、以下の流れで説明していきます。

VoiceOverを用いた読み上げ対応

iOSデバイスでは、VoiceOverというスクリーンリーダシステムを利用できます。このシステムは、以下手順によって有効にし、利用を開始できます。

  1. 設定(Settings)アプリを開く
  2. アクセシビリティ(Accessibility)を選択する
  3. VoiceOverを選択する
  4. VoiceOverをONに

VoiceOver設定画面の下部にあるキャプションパネルを有効にすると、読み上げられた文言が画面下部に表示されます。開発時に便利なので、有効にしておくことをお勧めします。

なお、SimulatorではVoiceOverを利用できません(設定アプリ中に、VoiceOverの項目が存在しません)。読み上げの動作確認には、Developer Toolに含まれるAccessibility Inspectorを用いるか、あるいは実機デバイスで行うのが良いでしょう。

Accessibility Inspectorは、XcodeのメニューバーからOpen Developer Toolを選び、内部にある同名の項目を選ぶことで起動できます。
Accessibility Inspectorは、Xcodeのメニューバーから起動できます。

Accessibility Inspectorで読み上げの動作を確認する場合、ウインドウ左上で検査対象デバイスを選択し、その右手にある照準ボタンを押した上で検査したいViewを選択します。これにより、Accessibility Inspector上に選択したViewの情報が表示されます。Quicklookで表示されている文言が実際に読み上げられる文言です。その右にあるスピーカーボタンを押すと、音声が再生されます。

Accessibility Inspectorで実際に検査してみた例
Accessibility Inspectorで実際に検査してみた例

Accessibility Inspectorを用いることで、VoiceOverが利用できないSimulatorでも読み上げの動作確認が可能となります。ただし、Accessibility Hintに設定した文言が読み上げられなかったり、VoiceOver rotor機能が無いため、コンテナや見出し、ランドマーク単位での読み上げの移動ができないなどの制限があります。簡易的な読み上げの検査にはSimulatorとAccessibility Inspectorの組み合わせで対応できますが、しっかりとVoiceOver対応するのであれば、実機デバイスでVoiceOverを用いる検査が不可欠です。

ロービジョンの方にとって有用であることはもちろんですが、視力が良い人であっても、直射日光下では画面の照り返しによって表示内容が見えづらかったり、また電車内等でスマートフォンを取り出せない状況も考えられます。このような画面を見ることができない場合でも、VoiceOverを用いればアプリの操作が可能となります。ロービジョンの方だけでなく、全てのユーザにとって恩恵があります。アプリ利用の幅を拡げられることから、是非対応したいですね!

VoiceOverに対応する上で、以下のことに気を配る必要があります。ここからは、それぞれの項目について説明していきます。

  • 読み上げられる文言の付与
  • Viewのグルーピング
  • コンテンツやレイアウトの動的な変化の読み上げ
  • Accessibility Traitsの付与

読み上げられる文言の付与

UIKitが提供しているものを用いてアプリを作っていけば、エンジニアが読み上げられる文言を明示的に設定せずとも、そのViewが表示している文言と、そのViewの種別(静的テキストや、ボタンなど)を適切に読み上げてくれます。

エンジニアが読み上げられる文言を意識しないといけないのは、以下のケースです。

  • 画像のみのView
  • 意味のある画像を併記したView(例えば、外部ブラウザ遷移を示すアイコンが文言の後に付与されているボタン)
  • 表示されている文言をそのまま読み上げても、ユーザに意味が伝わらないView(リスト中で何番目にあるのかに意味があったり、文言以外、例えば枠線色で意味を持たせているような、視覚に依存した情報提示をしているView)
  • 外部のWebページやアプリに遷移するようなボタン
    • 事前情報なく遷移してしまうと、画面上に表示されたものが何であるか、どういう状態になったのかを一から把握しなければならなくなる。これを防ぐため、ボタン操作で次どういう状態になるのかを読み上げ時に同時に伝えるのが望ましい

読み上げられる文言の付与に際し、エンジニアは以下を考慮する必要があります。

  • 動的に表示内容が変化するようなViewは、読み上げられる文言をロジックコードで動的に構築し、設定する必要がある
  • UIKitが提供するコントロールを拡張して実現するようなViewや、そもそも一から自作しないといけないようなViewがデザインで指定されているなら、デザイナに標準のコントロールを用いたデザインにできないか相談する
    • OSが提供するコントロールであれば、あらかじめアクセシビリティサービスに配慮した実装になっており、Viewの状態を自動で読み上げてくれたりします。自分でViewを作り込む場合、この辺りも自作しないといけません
  • 課金など条件をクリアしないとアクセスできない仕様のコンテンツに対し、VoiceOverによって不正にアクセスできる状態にないか(例えば、有料会員しか読めないニュース本文を画面に表示し、その上にグレー背景をオーバーレイし有料会員登録を促す画面をモーダル表示している場合、VoiceOverによって読み上げるViewを変えていくと、会員登録せずともニュース本文の全文を読み上げられる1

エンジニアが対応するにあたって、デザイナから以下のインプットが必要となります。

  • 読み上げる必要のある画像に対する文言
    • 同じ意味を持つ文言がViewに併記されているなら、読み上げられる文言を重複して設定する必要はありません
  • 表示されている文言とは異なる文言を読み上げて欲しい場合は、その文言

読み上げられる文言をInterface Builderで実装する場合、Identity InspectorでAccessibilityをEnabledにした上で、その下にあるLabelやHintに文言を設定します。

Interface BuilderでAccessibility LabelやHintを設定する画面サンプル
Interface BuilderでAccessibility LabelやHintを設定する

動的に文言が変化する(例えば、APIからのレスポンス値によって表示内容が変化する)場合は、コードにて設定すると良いです。isAccessibilityElementtrueに設定し、accessibilityLabelaccessibilityHintに文言を設定します。

読み上げられる文言は、以下の各点を押さえたものであることが望ましいです。

  • 簡潔であること
    • 特に、点字ディスプレイを利用されているユーザの場合、一度に表示できる文字数が16〜40文字程度と制限される(点字ディスプレイの機種による)ため
  • 物理的な操作方法を示す文言(クリック、タップ、押下)を含めないこと
    • SwitchやVoiceOver、キーボードなど、アプリを操作する手段は様々であり、これら文言を含めてしまうと特定の操作方法に対し不適切である可能性があります
  • 文脈的に最も重要な情報を、読み上げられる文言の頭に持ってきていること
    • 読み上げられる文言をいちいち最後まで再生させる必要がなくなるため、より速く、より快適にアプリを利用していただけます

Viewのグルーピング

Viewを実装する際に、VoiceOverにどの順序で読み上げて欲しいかについて、デザイナと認識を合わせておく必要があります。Viewの階層構造を作る際に、VoiceOverの挙動を意識しておかないと、読み上げられる順序が意図と異なる挙動を示す場合があります(Viewをタイル状に並べる場合、何も意識しなければ、左から右・上から下に読み上げられます。これと異なる読み上げ順序とする場合は、Viewのグルーピングに気を配る必要があります)。

また、Viewが適切にグルーピングされていない場合、小項目を一つずつなぞっていくしか読み上げを進める方法がなく、小項目の要素数が多いと操作性が悪くなります。例えば、複数の曲情報が表示されるような画面で、曲単位でのViewのグルーピングがなされていない場合、各曲の曲名やアーティスト情報を一つずつ読み上げていかなければなります。

Viewをグルーピングする場合、まずはそれらをUIViewクラスなどでまとめます。まとめたUIViewクラスにて、accessibilityElementsプロパティをオーバーライドします。そのGetterにてUIAccessibilityElementを活用して要素をまとめ、グループのフレームサイズ(VoiceOverが認識するタップ領域)をaccessibilityFrameInContainerSpaceに設定し、accessibilityLabelaccessibilityHintを設定し、作り上げたUIAccessibilityElementの配列を返すように実装すると良いでしょう(サンプルコード)。

class SampleView: UIView {
  ...
  private var _accessibilityElements: [Any]?
  override var accessibilityElements: [Any]? {
    set {
      _accessibilityElements = newValue
    }

    get {
      if let _accessibilityElements = _accessibilityElements {
        return _accessibilityElements
      }

      var elements = [UIAccessibilityElements]()
      let groupOneElement = UIAccessibilityElement(accessibilityContainer: self)
      groupOneElement.accessibilityLabel = "\(oneTitleLabel.text), \(oneValueLabel.text)"
      groupOneElement.accessibilityFrameInContainerSpace = oneTitleLabel.frame.union(oneValueLabel.frame)
      elements.append(groupOneElement)

      let groupTwoElement = UIAccessibilityElement(accessibilityContainer: self)
      groupTwoElement.accessibilityLabel = "\(twoTitleLabel.text), \(twoValueLabel.text)"
      groupTwoElement.accessibilityFrameInContainerSpace = twoTitleLabel.frame.union(twoValueLabel.frame)
      elements.append(groupTwoElement)

      _accessibilityElements = elements
      return _accessibilityElements
    }
  }
}

Viewのグルーピングに際して、エンジニアは以下を考慮する必要があります。

  • Viewの階層構造と読み上げ順序が一致していること
    • 左から右・上から下という読み上げ順序から乖離したデザインの指示(読み上げの順序が直線的ではない、とか、下から上・右から左に読み上げさせようとしている)をデザイナからいただいた場合、デザインに根本的な問題がある可能性があるため、デザイナと対応を相談する必要があります

エンジニアが対応するにあたって、デザイナから以下のインプットが必要となります。

  • 読み上げ順序が不明瞭な箇所に対する、順序の指定
  • 塊で読み上げて欲しい箇所があれば、その部分の明示
  • 塊を、その内部のViewが持つ文言ではなく別の文言で読み上げて欲しい場合は、その読み上げ文言の指定

Viewの階層構造やViewのグルーピングに関して、以下の各点を押さえておくと良いでしょう。

  • Viewの階層構造と、画面上で見えるViewのグルーピングと、読み上げられる順序を考慮する
    • デザイナは、左から右・上から下という直線的な順序で自然に読み上げられるようデザインする
    • エンジニアは、デザイナと認識を合わせた読み上げ順序となるよう意識し、View階層を実装する
  • 関連するViewをVoiceOverが認識できる形でまとめようとすると、Viewの階層構造が複雑にならざるを得ない場合がある

コンテンツやレイアウトの動的な変化の読み上げ

ここまでで扱ってきたものは、いずれもユーザが明示的にフォーカスを当てたものをVoiceOverで読み上げさせるものでした。

これとは異なり、ある操作を起点として画面上のコンテンツやレイアウトに変化があった場合、VoiceOverユーザにその変化を伝えるべき場合があります。これを実現するためには、UIAccessibility.post(notification:argument:)を用います。

notification:にはどのようなUIの更新があったのか、その種別を渡します。主に以下のいずれかを用いることになります。

  • screenChanged
    • 画面の多くを占める形で、新しいViewが表示された場合(例えば、モーダル表示)
    • トーンを鳴らして変化をユーザに伝え、表示されているコンテナの最初のAccessibility Element(isAccessibilityElementがtrueなView)にフォーカスが当たり読み上げられる
  • layoutChanged
    • 一部のViewが更新された場合(Viewの表示・非表示が切り替わった場合や、ボタンの有効・無効が切り替わった場合など)
    • argument:に更新されたAccessibility Elementや任意の文言を渡し、Viewが更新されたことをユーザに伝える
  • announcement
    • UIの更新がない、あるいはほんの少ししか更新されないようなイベントが発生した場合(画面のローディング状態など)
    • argument:に任意の文言を渡し、ユーザに伝える

screenChangedなNotificationでargument:にAccessibility Elementを渡した場合、トーンが鳴った後、渡したAccessibility Elementにフォーカスが当たり読み上げられます。文言を渡した場合、トーンが鳴った後、渡した文言が読み上げられ、表示されているコンテナの最初のAccessibility Elementにフォーカスが当たり読み上げられます。

layoutChangedannouncementargument:にnilを渡した場合、何も起きません。

頻繁に更新されるようなViewに対してこれを実装すると、その更新の度に読み上げが実行されてしまいます。これはユーザのアプリ操作を阻害し混乱を生じさせ、アプリが使い物にならなくなる原因となる可能性があります。濫用せず、バランスを見て適切に用いるのが良いでしょう。

Accessibility Traitsの付与

Accessibility Elementがどのような振る舞いをするのかを示すのが、Accessibility Traitsです。

ユーザに対し、そのViewがボタンなのか、リンクなのか、テキストなのか、また操作が可能なのか等を示す手段であり、これを適切に設定することによって、VoiceOverにて指定した振る舞いが読み上げられ、ユーザが適切にアプリを操作できます。

ユーザに誤解を与えないように、Viewの用途を考慮し適切にTraitsを選ぶ必要があります(例えば、操作によって外部ブラウザが開くのであれば、そのViewがボタンの形をしていてもLinkを設定することが望ましいです)。

Interface Builderで実装する場合、Identity InspectorでAccessibilityをEnabledにした上で、Traitsでリストアップされている中から適切なものを有効にします。

Interface BuilderでAccessibility Traitsを設定する画面サンプル
Interface BuilderでAccessibility Traitsを設定する

Viewの振る舞いが動的に変化する場合は、コードで設定すると良いです。isAccessibilityElementをtrueに設定し、accessibilityTraitsに適切なUIAccessibilityTraitsを設定します。

タッチ領域の確保

タッチ操作可能なViewについて、タッチ操作可能な領域を最低でも 44pt × 44pt は確保してください。

タッチ操作可能な領域が狭いと、指が太かったり運動技能が低下している人だけでなく、全ての人にとってアプリの操作がしづらくなり、不快感を持たれる原因となります。

アプリを実装する際に、エンジニアは以下の項目に配慮すると良いです。

  • 小さい画像のみのボタンを実装する場合、タッチ操作可能な領域が十分に確保できているか(44pt × 44pt)を確認する
  • タッチ操作可能なViewが隣接している場合、間隔が詰まり過ぎていないかを確認する

デザイナは、以下を考慮してアプリをデザインすると良いです。

  • タッチ操作可能なViewは、最低でも 44pt × 44pt のタッチ操作可能な領域を確保できるよう、隣接するViewとの間隔を調整する
  • タッチ操作可能なViewが隣接している場合、間隔を空けて空間が詰まり過ぎないようにする
    • 情報の密度と、タッチ操作のしやすさのバランスをとる

Dynamic Typeの対応

文字の読みやすさを向上させるため、ユーザはDynamic Typeを用いてシステムのフォントサイズを拡大させる可能性があります。アプリ側は、Dynamic Typeに対応させてアプリ内のフォントサイズを設定に追従させることと、最大のフォントサイズを設定された場合でもレイアウトが崩れないよう対応することが望ましいです。

iOSでDynamic Typeにアプリを対応させ、Dynamic Typeによるフォントサイズ変更に追従してアプリ内のフォントサイズも変更させる場合、まずは以下のいずれかの方法でフォントを指定する必要があります2

  • Dynamic Type用に用意されたText Stylesの中から選んだものを、フォントに指定する
    • Interface Builderでは、Font設定内部でText Stylesとしてリストアップされているもののうち、いずれかを選ぶ
    • コードでは、UIFont.preferredFont(forTextStyle:)で指定する
  • システムフォントやカスタムフォントを用いる場合、iOS 11以降で導入されたUIFontMetricsクラスを用いる
    • label.font = UIFontMetrics.default.scaledFont(for: .systemFont(ofSize: 16))

フォントを指定したら、Dynamic Typeによる設定変更が自動的にアプリ内のフォントサイズへ反映されるよう実装します。

  • フォントをInterface Builderで指定した場合は、フォント設定の下にあるAutomatically Adjusts Fontを有効にする
  • フォントをコードで指定した場合は、フォント指定したインスタンスのadjustsFontForContentSizeCategoryを有効にする

ここまで実装することで、Dynamic Typeに対応できます。

アプリをDynamic Typeに対応させる場合、エンジニアは以下の項目に配慮すると良いです。

  • フォントサイズを変更した場合や、表示する文字数が多い場合にレイアウトが崩れないかを確認する
    • 文言が見切れる場合、文言を省略するのか(省略するならどこを省略するのかまで含めて)、改行するのかをデザイナに確認する3
  • フォントサイズの拡大に追従して、意味のあるGlyphのサイズも合わせて拡大させる

また、エンジニアが対応するにあたって、デザイナから以下のインプットが必要となります。

  • Dynamic Typeに対応して欲しくない場合、それがエンジニア側に分かるように示し、理由も説明する
  • 文字数が多い場合、またはフォントサイズの変更により文言が見切れてしまう場合の対応方針をエンジニア側に示す
    • 文言を折り返して複数行で表示するのか、文言の一部を省略して1行で表示するのか
    • 文言を省略するなら、先頭・中間・末尾のどの位置で省略するのか

コントラスト比の確保

前景色(文字色など)と背景色のコントラスト比が十分でない場合、ロービジョンの方や直射日光下で画面の照り返しがキツい場合などで画面上の情報を読み取ることが困難になります。

WCAG 2.14では、文字画像を含むテキストに対し、大文字や太字の場合は最低限のコントラスト比を3:1、非アクティブなViewの一部・装飾目的・誰も視認できない・重要な他の視覚的なコンテンツを含む写真の一部・ロゴタイプ、という条件に当てはまらないものについて最低限のコントラスト比を4.5:1とし、これに適合するか超えるように色を設定すべきだとしています(参考)。

また、コンテンツを理解するために必要なアイコン等の画像については、少なくとも3:1のコントラスト比が求められています(参考)。

Human Interface Guidelinesでは、フォントサイズが18pt以上か、あるいはフォントがBoldであれば最低限のコントラスト比を3:1とし、それ以外の場合は4.5:1を最低限のコントラスト比とするよう記載されています。

デバイスのアクセシビリティ(Accessibility) -> 画面表示とテキストサイズ(Display & Text Size)にあるコントラストを上げる(Increase Contrast)設定に関連して、Human Interface Guidelinesでは以下の記載があります。

When you color text using the colors defined by UIColor or NSColor, the text responds correctly to accessibility settings such as Invert Colors and Increase Contrast.

このように記載されていますが、UIColorやNSColorで色を定義すれば、あとは何もしなくてもシステム側でよしなにコントラスト比を上げてくれる、という訳ではありません。

Human Interface Guidelinesで記載されているSystem Colorsを用いている場合は、コントラストを上げる設定に応じて通常の色とハイコントラストな色の切り替えが自動で行われます。

そうではなく、自前で用意した色を定義する場合は、通常の色を定義する際に、同時にハイコントラストな色も用意し定義しなければなりません。

Xcode Asset CatalogのColor assetsを用いて色を定義する場合、Attributes InspectorのAppearancesにHigh Contrastというチェックボックスがあるので、これにチェックを入れ、新たに表示されるハイコントラスト用の色定義に対し色を設定します。

コードで色を定義している場合、iOS 13以降で導入されたUIColorのinit(dynamicProvider:)を用い、通常の色定義とハイコントラストな色定義をUITraitCollection.accessibilityContrastを判断材料にswitch case文で出し分けるように実装すれば良いでしょう(参考)。

あるいは、手間がかかりますがdarkerSystemColorsStatusDidChangeNotificationコントラストを上げる設定が変更された通知を受け取り、これを契機に色を切り替えるよう実装するという方法もあります(参考)。

アプリを実装する際に、エンジニアは以下の項目を確認すると良いです。

  • 画像の上に文字を置くようなレイアウト構造の場合、画像の色と文字色の組み合わせによってはコントラスト比が下がる可能性がある。このようなレイアウトの指示がある場合は、コントラスト比を保つ方法をデザイナと相談する
  • ボタンにフォーカスが当たった際に、特定の色をのせてフォーカスされていることを示すレイアウトになっている場合、色がのることでコントラスト比が下がる可能性がある(例えば、黒文字のボタンでフォーカス時に透過グレーをボタンにのせる、とか)。このようなレイアウトの指示を見つけたら、デザイナにコントラスト比を考慮できているか確認をとる

コントラスト比に関しては、デザイナ側からいただいたレイアウトの指示において、既に考慮がなされている想定です。そのため、エンジニアが対応するにあたってデザイナから別段のインプットは不要です。

上述したとおり、System Colorsではなく自前で用意した色を用いる場合で、なおかつコントラストを上げる設定にアプリを対応させる場合は、通常の色だけではなくハイコントラストな色もデザイナから提供いただく必要があります。

色以外での手がかりの提供

色に情報を持たせている場合(例えば、外部リンクであることを示すために、文字色を青色にする)、色以外でもその情報が認識できるような手がかりを加えるべきです(例えば、テキストに下線を引く)。色弱の方や、直射日光下で画面の照り返しがある等の状況下で色の識別が難しい場合でも、色以外の手がかりを提供することで、情報の認識が容易となります。

アプリを実装する際に、エンジニアは以下の項目に配慮すると良いです。

  • 色のみに情報を持たせているViewがないかを確認し、あれば色以外でも情報を認識できる手がかりを加える
    • 例えば、外部リンクを示すテキストに対しては、文字色を変えるだけではなく、下線を引く
    • 例えば、入力値にエラーがあることを示す場合、色で示すだけではなく、テキストでもエラーであることを示す
    • アイコンの色のみでステータスを示すようなものがあれば、アイコンの形も変えるようデザイナに伝える

デザイナは、以下を考慮してアプリをデザインすると良いです。

  • 色しか手がかりのない情報の示し方は避ける

ジェスチャ操作に代わる操作方法の提供

ジェスチャ操作が難しい場合を想定し、ジェスチャ操作以外で同じ結果を得られる代替手段(例えば、UITableViewの行削除で、スワイプ操作によるものだけではなく、Edit Modeによって表示されるボタンからでも削除可能にする)を用意すると良いです。

アプリを実装する際に、エンジニアは以下の項目に配慮すると良いです。

  • ジェスチャ操作によって機能を実現する場合、ジェスチャ操作を用いずとも同等の操作が可能となる方法を用意する
  • ジェスチャ操作を用いない代替手段をシステムが提供している場合は、それを用いる

デザイナは、以下を考慮してアプリをデザインすると良いです。

  • 機能の実現にジェスチャ操作を用いる場合、ジェスチャ操作以外で同じ結果を得られる方法を用意し、デザインに盛り込む
    • システムが代替手段を提供していないかを確認する(例えば、UITableViewのEdit Mode)

適切に対応できていることを確認する方法

ここまでで説明してきた各項目について、適切に対応できているかを確認するための方法を記します。

VoiceOver

実際にVoiceOverを起動し、読み上げとナビゲーションに問題がないかを確認します。SimulatorとAccessibility Inspectorで確認することも可能ですが、あくまで簡易的で、上述したように一部読み上げができない場面があるため、実機デバイスにて動作確認することが望ましいです。

特に、以下の項目に注意して確認していくのが良いでしょう。

  • タップして操作できるViewについて、Traitsの読み上げからユーザがタップ操作可能であると認識できるか(例えば、タップして詳細画面に遷移するUITableViewCellのTraitsが静的テキストになっていた、とか)
  • 読み上げられる文言が適切か。アセットのファイル名がそのまま読み上げられる等の不正な挙動になっていないか
  • 読み上げさせてはいけない箇所が、読み上げ可能になっていないか(例えば、課金によって初めてアクセス可能な文言)

また、Accessibility InspectorのAuditで、Element has no descriptionImage name used in descriptionPotentially inaccessible textといった警告が出ていないかを確認すると良いでしょう。

Accessibility InspectorのAuditで、“Potentially inaccessible text”の警告が出ている例
Accessibility InspectorのAuditで、“Potentially inaccessible text”の警告が出ている例

タッチ領域の確保

Accessibility InspectorのAuditで、Hit area is too smallという警告が出ていないかを確認すると良いでしょう。

Accessibility InspectorのAuditで、“Hit area is too small”の警告が出ている例
Accessibility InspectorのAuditで、“Hit area is too small”の警告が出ている例

Dynamic Type

Accessibility InspectorのAuditで、Dynamic Text font sizes are unsupportedという警告が出ていないかを確認すると良いでしょう。

Accessibility InspectorのAuditで、“Dynamic Text font sizes are unsupported”の警告が出ている例
Accessibility InspectorのAuditで、“Dynamic Text font sizes are unsupported”の警告が出ている例

また、実際にDynamic Typeでフォントサイズを最大まで拡大し(さらに大きな文字も有効にした上で)、文言が見切れたり、レイアウトが崩れていないかも確認しましょう。フォントサイズを変更する際は、Accessibility InspectorのSettingsにあるFont sizeスライダーを用いるのがおすすめです。また、Xcode 11以降を利用されている場合は、Environment Overridesによっても変更が可能です。

Xcode 11以降で追加されたEnvironment Overridesを開いている例
Xcode 11以降で追加されたEnvironment Overridesを開いている例

コントラスト比の確保

Accessibility InspectorのAuditで、Contrast failedあるいはContrast nearly passedという警告が出ていないかを確認すると良いでしょう。

Accessibility InspectorのAuditで、“Contrast nearly passed”の警告が出ている例
Accessibility InspectorのAuditで、“Contrast nearly passed”の警告が出ている例

特に、Contrast failedという警告が出ているものについては、コントラスト比が上がるように色を見直すことが望ましいです。

ただし、アイコン等の画像に対して、文字画像を含む太字・大文字でないテキストで最低限求められるコントラスト比である4.5:1の閾値を当てはめている場合があります。コンテンツを理解するために必要なアイコン等の画像については、少なくとも3:1のコントラスト比が求められており、対応しなくとも良い場合があります。警告が出た場合、その詳細を確認し、対応が必要かを検討する必要があります。

おわりに

iOSアプリのアクセシビリティを向上させるために、考慮すべきこと、エンジニア側の視点でデザイナからどのようなインプットが必要なのか、適切に対応できたことをどのように確認するのか、について書きました。考えるべき項目が多く、対応するのは大変かな、と思われた方もいるかもしれません。ですが、これらはいずれもアプリを実装する前のデザイン・設計の段階で考慮しておけば、追加の手間はほとんど必要とならず、簡単に対応できるものばかりだと思います。

あらゆる人がどのような環境でも利用でき、より多くの人たちに利用され、永く愛されるアプリにするために。ここまで読んでくださったあなたも、はじめてみませんか?


参考


  1. DroidKaigi 2020 - 残り15%のユーザーにリーチするためのAccessibility / coffeegyunyu [JA]にて例示されていました。

  2. Android側は、フォントサイズをsp単位で指定することによって、同等のことを実現できます。

  3. Human Interface GuidelinesAccessibility/Text Size and Weightにて、“As font size increases, avoid truncating text.”とあるように、詳細画面のような別画面で全文を参照できる場合を除き、文言の省略は避け、文言を折り返してスクロール操作によって全文読めるよう対応することが望ましいとされています。

  4. Web Content Accessibility Guidelines。読んで字の如くWebコンテンツ向けのアクセシビリティガイドラインではあるが、スマートフォンアプリに対しても適用できるルールが多く、アクセシビリティを学ぶ際は必ず目を通すべきガイドラインです。