スクリーンリーダー(Screen Reader)は、テキストやグラフィカルなインターフェース要素を音声または点字ディスプレイ出力に変換し、視覚障害のあるユーザーが視覚的コントロールなしでデバイスを操作できるようにするプログラムです。モバイルプラットフォームでは、主要なスクリーンリーダーはiOSのVoiceOverとAndroidのTalkBackです。世界保健機関(2023年)によると、スクリーンリーダーは世界中の2億8500万人の視覚障害者にとってデジタル技術への主要なアクセスツールです。
重要なポイント
スクリーンリーダー(Screen Reader)は、グラフィカルユーザーインターフェースを解釈し、合成音声や触覚点字ディスプレイを通じて非視覚的な形で提示する支援技術(Assistive Technology, AT)です。スクリーンリーダーは、全盲または部分的な視力喪失のある人々にとって、コンピューターやモバイルデバイスにアクセスする主要な手段です。
最初のスクリーンリーダーは1980年代後半にMS-DOS用(例:Vocal-Eyes)として登場し、その後Windows用(JAWS、NVDA)が登場しました。モバイルプラットフォームでは、スクリーンリーダーはシステムレベルで統合されました。Appleは2009年にiPhone 3GSにVoiceOverを統合し、Googleは同じ年にAndroid 1.6にTalkBackを統合しました。2025年までに、ほとんどすべての最新スマートフォンには、追加のソフトウェアインストールを必要としない内蔵スクリーンリーダーが搭載されています。
スクリーンリーダーは単に画面のテキストを読むだけではありません。インターフェースの階層を分析し、要素の種類(ボタン、リンク、見出し、入力フィールド)、その状態(有効/無効、選択済み/未選択)、および関係(親子、グループ)を特定します。この情報は、フォーカス位置に応じてリアルタイムにセルを更新する点字ディスプレイの音声プロンプトや触覚を通じてユーザーに伝えられます。
スクリーンリーダーはオペレーティングシステムと密接に連携し、その内部インターフェース表現であるアクセシビリティツリー(Accessibility Tree)にアクセスします。このメカニズムはiOSとAndroidで同じですが、API名は異なります。
スクリーンリーダーの主要な出力チャネルは音声合成エンジン(Text-To-Speech、TTS)です。アクセシビリティフォーカスが要素に当たると、スクリーンリーダーはそのテキストコンテンツ(または開発者が指定した説明)を抽出し、TTSエンジンに送信します。Apple Speech SynthesisやGoogle Text-to-Speechなどの最新のTTSエンジンは、ニューラルネットワークを使用して、句読点やコンテンツタイプに応じて適切なイントネーション、ポーズ、強調を含む自然な音声を生成します。
ユーザーは読み上げ速度(通常、快適な知覚のために最大値の60~80%)、ピッチ、音量を調整できます。一部のスクリーンリーダーは複数の音声をサポートし、コンテンツタイプに応じてそれらを切り替えます。たとえば、テキスト読み上げ用の低速音声とインターフェースナビゲーション用の高速音声などです。点字ディスプレイはBluetooth経由で接続し、一度に40~80文字を表示し、フォーカスが変わるたびに行を更新します。
スクリーンリーダーは、標準の入力フォーカスとは異なるアクセシビリティフォーカス(Accessibility Focus)の概念を使用します。ユーザーはジェスチャー(タッチ、スワイプ)でアクセシビリティフォーカスを移動し、スクリーンリーダーはフォーカス下の要素を読み上げます。ナビゲーション順序はデフォルトで視覚的な順序(左から右、上から下)に従います。開発者は複雑なレイアウトのためにこの順序を上書きできます。
スクリーンリーダーは、ユーザーがローター(VoiceOver)やメニュー(TalkBack)で切り替えるさまざまなナビゲーションモードもサポートしています:見出し、リンク、文字、単語、フォームごと。見出しモードでは、スクリーンリーダーはH1~H6間のみを移動します。これは長いページやドキュメントの効率的なナビゲーションに重要です。文字モードは確認コードや複雑なパスワードの入力時に役立ち、各文字を個別に発音します。
モバイルプラットフォームでは、iOSのVoiceOverとAndroidのTalkBackの2つのスクリーンリーダーが主流です。API、ジェスチャー、機能は異なりますが、共通の原理はアクセシビリティツリーの読み取りとジェスチャーコントロールです。
VoiceOverはAppleのスクリーンリーダーで、iOS、iPadOS、macOSに組み込まれています。要素に関する情報を取得するためにUIAccessibility APIを使用し、ナビゲーションモードを切り替えるローターをサポートしています。VoiceOverはiCloud(デバイス間での設定同期)、Apple Pay(Touch IDまたはFace IDによる支払い確認)、ダイナミックテキスト(フォントがユーザー設定に適応)と統合されています。
VoiceOverのジェスチャーはTalkBackとは異なります:2本指の回転(ローター)、スクリーンカーテン用の3本指タップ、アクションキャンセル用の2本指ダブルタップを使用します。VoiceOverは、開発者がUIAccessibilityCustomRotorを通じて追加するカスタムローターをサポートしています。たとえば、標準の順序をバイパスしてアプリセクションをすばやくナビゲートするためのものです。
TalkBackはGoogleのスクリーンリーダーで、Android Accessibility Suiteの一部です。インターフェースにアクセスするためにAccessibilityServiceとAccessibilityNodeInfoを使用します。TalkBackはL字型スワイプによるグローバルメニュー、要素のカスタムアクション、動的更新のためのLiveRegionをサポートしています。Android 14以降、TalkBackは片手ジェスチャーサポートとGoogle Assistantとの統合改善を獲得しました。
TalkBackはVoiceOverよりも柔軟なジェスチャーシステムを備えています。ユーザーはほぼすべてのジェスチャーを任意のアクションに割り当てることができます。TalkBackは画面上の点字入力(BrailleBack)もサポートしています。ユーザーは指ごとに特別な3×2レイアウトでタッチスクリーン上に直接点字文字でテキストを入力します。これにより、画面上のキーボードと比較してテキスト入力が大幅に高速化されます。
| 特徴 | VoiceOver(iOS) | TalkBack(Android) |
|---|---|---|
| API | UIAccessibility | AccessibilityService |
| ナビゲーション | ローター(2本指) | グローバルメニュー(Lスワイプ) |
| 言語 | 40以上 | 30以上 |
| カスタムアクション | UIAccessibilityCustomRotor | AccessibilityDelegate |
| 点字 | 外部ディスプレイ | BrailleBack + 外部 |
| 動的更新 | UIAccessibility.post | accessibilityLiveRegion |
VoiceOverとTalkBackの他に、あまり一般的ではないモバイルスクリーンリーダーもあります:Select to Speak(Android、選択領域を読み上げ)、Samsung Voice Assistant(One UI搭載SamsungデバイスでTalkBackを置き換え)、特定のニッチ向けのサードパーティソリューション(Googleサービスなしの中国製スマートフォンユーザー向けなど)。
スクリーンリーダーはアプリのUIコンポーネントに直接アクセスできません。代わりに、オペレーティングシステムのアクセシビリティAPIというレイヤーを通じて機能します。オペレーティングシステムはアクセシビリティツリー(Accessibility Tree)を構築し、スクリーンリーダーがそれをトラバースして分析します。
iOSでは、アクセシビリティツリーは画面上の各Viewに対応するUIAccessibilityElementオブジェクトから構築されます。各要素には、label(メインテキスト)、traits(要素タイプ:ボタン、見出し、リンク)、hint(ツールチップ)、value(スライダーやインジケーターの現在値)、frame(タッチ領域)が含まれます。システムは標準のUIコンポーネントの要素を自動的に作成しますが、開発者は要素を追加およびカスタマイズできます。
Androidでは、アクセシビリティツリーはAccessibilityNodeInfoオブジェクトから構築されます。各ノードには、text(テキストまたはcontentDescription)、className(要素タイプ)、contentDescription(説明)、stateDescription(状態)、isEnabled、isChecked、isClickableなどのフラグが含まれます。AndroidはAccessibilityActionもサポートしています。これはスクリーンリーダーがユーザーに代わって実行できるアクション(クリック、長押し、スクロール、フォーカス設定、テキスト設定)のリストです。
インターフェースで変更が発生すると(新しい要素の出現、テキストの変更、要素の表示/非表示)、オペレーティングシステムはAccessibilityEventを送信します。スクリーンリーダーはこれらのイベントをサブスクライブし、それらに反応します。たとえば、ダイアログが表示されると、スクリーンリーダーは自動的にフォーカスをそのタイトルに移動し、コンテンツを読み上げます。
// Androidでのアクセシビリティイベントのリッスン
class CustomAccessibilityService : AccessibilityService() {
override fun onAccessibilityEvent(event: AccessibilityEvent?) {
event ?: return
when (event.eventType) {
TYPE_VIEW_CLICKED ->
handleClick(event)
TYPE_WINDOW_STATE_CHANGED ->
handleWindowChange(event)
TYPE_VIEW_TEXT_CHANGED ->
handleTextChange(event)
}
}
}
iOSでは、同様のイベントはUIAccessibility.Notificationを通じて処理されます:layoutChanged(レイアウト変更)、screenChanged(完全に新しい画面)、announcement(カスタム読み上げ)、pageScrolled(ページスクロール)。開発者はUIAccessibility.postを介してこれらのイベントを送信し、スクリーンリーダーが変更に正しく応答できるようにします。たとえば、モーダルウィンドウを開くときは、新しいタイトルを含むscreenChangedを送信する必要があります。そうしないと、VoiceOverはウィンドウの下の以前の要素に留まったままになります。
アクセシブルなアプリを作成することは、すべての要素にcontentDescriptionを追加することではなく、非視覚的なインタラクションのためのユーザーエクスペリエンスを設計することです。基本的なルールは両方のプラットフォームで同じですが、実装は異なります。
すべてのインタラクティブ要素には意味のある説明が必要です。「送信」ボタンは単に「ボタン」ではなく「メッセージを送信」として説明されるべきです。装飾的な要素(区切り線、背景画像、機能しないアイコン)はスクリーンリーダーから隠す必要があります。ナビゲーション順序は視覚的なレイアウトではなく、画面の論理的な流れに従う必要があります。テキストのコントラストは、本文テキストで少なくとも4.5:1、大きなテキストで3:1(WCAG AA)である必要があります。
// iOS: 複雑な要素の正しい設定
let customControl = UIControl()
customControl.isAccessibilityElement = true
customControl.accessibilityLabel = "音量"
customControl.accessibilityValue = "75パーセント"
customControl.accessibilityTraits = [
.adjustable,
.button
]
customControl.accessibilityHint =
"音量を上げたり下げたりします"
// 値変更時の更新
func didChangeVolume(newValue: Float) {
customControl.accessibilityValue =
"\(Int(newValue))パーセント"
UIAccessibility.post(
notification: .layoutChanged,
argument: customControl
)
}
iOSでは、isAccessibilityElementフラグがカスタム要素のVoiceOverサポートを有効にします。traitsの組み合わせ(.adjustable + .button)は、要素が上下スワイプで調整可能で、ダブルタップでアクティブ化できることをVoiceOverに伝えます。値を変更した後は、layoutChanged通知を送信する必要があります。そうしないと、VoiceOverは古い値を読み上げ続けます。
iOSの場合:読み上げ順序を上書きするにはaccessibilityElements、コンテキストメニューの追加アクションにはaccessibilityCustomActions、要素を論理グループにまとめるにはshouldGroupAccessibilityChildrenを使用します。SwiftUIの場合は、.accessibilityLabel()、.accessibilityAddTraits()、.accessibilityRespondsToUserInteraction()モディファイアを使用します。インタラクティブな子要素を含むコンテナでisAccessibilityElement = falseを設定しないでください。それらがVoiceOverから隠されてしまいます。
Androidの場合:ナビゲーション順序にはaccessibilityTraversalBeforeとaccessibilityTraversalAfter、カスタム要素にはAccessibilityDelegate、動的更新にはLiveRegion(polite/assertive)を使用します。Composeでは、contentDescription、stateDescription、customActionsを含む.semantics {}モディファイアを使用します。非インタラクティブ要素でfocusable = trueを設定しないでください。TalkBackに誤ったフォーカスポイントが作成され、ユーザーを混乱させます。
スクリーンリーダーを使用したテストは物理デバイスで行う必要があります。エミュレーター/シミュレーターは基本的な理解を提供しますが、ジェスチャーと応答速度が異なります。iOSにはAccessibility Inspector(Xcode)、AndroidにはAccessibility Scanner(自動問題検出用)を使用します。
主要なテストシナリオ:登録(フォーム入力、検証、送信)、検索とカタログナビゲーション、チェックアウト、パスワードリカバリー。各シナリオは視覚的コントロールなしで完了可能でなければなりません。スクリーンリーダーの音声プロンプトのみを使用します。スクリーンリーダーユーザーが通常のユーザーと同じ時間(±50%)でシナリオを完了できない場合、アプリのアクセシビリティ改善が必要です。
よくある質問
スマートフォンの画面で起こるすべてのこと(テキスト、ボタン、通知)を読み上げるプログラムです。ユーザーはジェスチャーでデバイスを操作します。要素に触れて名前を聞き、ダブルタップでアクティブ化します。スクリーンリーダーは視覚を音声に置き換えます。
iOS — VoiceOver(Appleの内蔵システムスクリーンリーダー)。Android — TalkBack(GoogleのAndroid Accessibility Suiteの一部)。どちらもジェスチャーコントロール、音声フィードバック、Bluetooth経由の点字ディスプレイをサポートしています。
すべてのインタラクティブ要素にcontentDescription(Android)またはaccessibilityLabel(iOS)を設定します。装飾要素をスクリーンリーダーから隠します。動的変更時に通知を送信します。物理デバイスで視覚的コントロールなしにスクリーンリーダーを有効にしてテストします。
主な違いはAPIとジェスチャーです。VoiceOverはiOSでUIAccessibilityを使用し、ナビゲーションにローター(2本指回転)を使用します。TalkBackはAndroidでAccessibilityServiceを使用し、L字型スワイプによるグローバルメニューを使用します。動作原理(アクセシビリティツリーのトラバース)は同じです。
スクリーンリーダーは画像を「見る」ことができません。開発者がcontentDescription(Android)またはaccessibilityLabel(iOS)を通じて提供するテキスト説明を読みます。説明が設定されていない場合、スクリーンリーダーはファイル名を読むか、単に「画像」と言うだけです。これはユーザーにとって役に立ちません。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。