完全に理解する Storyboard & UIKit (Day 28): Accessibility(VoiceOver対応など)のUI設計
S7r1n9y
Engineer
このシリーズの記事一覧
- 1. 完全に理解する Storyboard & UIKit (Day 1): 基礎概念と歴史
- 2. 完全に理解する Storyboard & UIKit (Day 2): XcodeでのStoryboardの基本操作
- 3. 完全に理解する Storyboard & UIKit (Day 3): UIViewControllerのライフサイクル
- 4. 完全に理解する Storyboard & UIKit (Day 4): Auto Layoutの基本原理
- 5. 完全に理解する Storyboard & UIKit (Day 5): Auto Layoutの複雑な制約の解決
- 6. 完全に理解する Storyboard & UIKit (Day 6): UIStackViewを使った効率的なレイアウト設計
- 7. 完全に理解する Storyboard & UIKit (Day 7): Size Classesによるレスポンシブデザイン
- 8. 完全に理解する Storyboard & UIKit (Day 8): Segueによる画面遷移とデータ渡し
- 9. 完全に理解する Storyboard & UIKit (Day 9): Navigation Controllerの活用
- 10. 完全に理解する Storyboard & UIKit (Day 10): Tab Bar Controllerの活用
- 11. 完全に理解する Storyboard & UIKit (Day 11): 基本的なUI部品(UILabel, UIButton, UITextField)
- 12. 完全に理解する Storyboard & UIKit (Day 12): UITextViewとキーボードハンドリング
- 13. 完全に理解する Storyboard & UIKit (Day 13): UIImageViewと画像リソース管理
- 14. 完全に理解する Storyboard & UIKit (Day 14): UIScrollViewとコンテンツのスクロール
- 15. 完全に理解する Storyboard & UIKit (Day 15): UITableViewの実装基礎
- 16. 完全に理解する Storyboard & UIKit (Day 16): UITableViewのカスタムセル作成
- 17. 完全に理解する Storyboard & UIKit (Day 17): UICollectionViewの実装基礎
- 18. 完全に理解する Storyboard & UIKit (Day 18): UICollectionViewのカスタムレイアウト
- 19. 完全に理解する Storyboard & UIKit (Day 19): Custom Viewの作成とStoryboardでの利用(@IBDesignable, @IBInspectable)
- 20. 完全に理解する Storyboard & UIKit (Day 20): アニメーションの実装(UIView Animation)
- 21. 完全に理解する Storyboard & UIKit (Day 21): Gesture Recognizerによるタッチ処理
- 22. 完全に理解する Storyboard & UIKit (Day 22): UIAlertControllerによるアラートとアクションシート
- 23. 完全に理解する Storyboard & UIKit (Day 23): UIDatePickerやUIPickerViewの実装
- 24. 完全に理解する Storyboard & UIKit (Day 24): Storyboard Referenceを用いたStoryboard分割
- 25. 完全に理解する Storyboard & UIKit (Day 25): XIBとStoryboardの使い分け・併用
- 26. 完全に理解する Storyboard & UIKit (Day 26): UIAppearanceによるアプリ全体の色・スタイル管理
- 27. 完全に理解する Storyboard & UIKit (Day 27): ダークモード対応とアセットカタログ
- 28. 完全に理解する Storyboard & UIKit (Day 28): Accessibility(VoiceOver対応など)のUI設計
- 29. 完全に理解する Storyboard & UIKit (Day 29): UIKitからSwiftUIへの移行 / UIKitでのSwiftUI利用
- 30. 完全に理解する Storyboard & UIKit (Day 30): 実践:1つのアプリをStoryboardとUIKitで完成させる
Sponsored
完全に理解する Storyboard & UIKit (Day 28): Accessibility(VoiceOver対応など)のUI設計
美しいデザインや滑らかなアニメーションは素晴らしいですが、それらが見えづらい、あるいは全く見えないユーザーにとってアプリはどう映るでしょうか? Appleは全ての人に開かれたデバイスを作ることを理念としており、iOSには非常に強力なアクセシビリティ支援機能(特に画面読み上げの VoiceOver)が標準搭載されています。
UIKitで構築したUIに対して、ほんの少しの追加設定を行うだけで、何百万人もの視覚障害を持つ人々があなたのアプリを使えるようになります。
1. UIKitとVoiceOverの基本原理
iPhoneの設定から「VoiceOver」をオンにすると、画面を一度タップした要素の「役割」と「内容」をSiriが音声で読み上げ、ダブルタップで実行されるようになります。
UIKitの標準コンポーネント(UILabel, UIButtonなど)は、デフォルトでVoiceOverに対応しています。
例えば、UILabel に「設定」と書かれていれば「設定」、UIButton であれば「設定、ボタン」と自動的に読み上げてくれます。
しかし、開発者が手を加えないと「読み上げられない」、あるいは「不親切な読み上げ方になる」ケースが存在します。それを解決するのが UIAccessibility プロトコルです。
2. アイコンや画像に適切な読み上げラベルを設定する
最もよくある問題は、「文字情報を持たないImageViewやアイコンのみのボタン」です。 例えば、虫眼鏡のアイコンを置いた検索ボタンは、画面が見える人には伝わりますが、VoiceOverは「ボタン」としか読み上げず、役割が全く伝わりません。
Storyboardでの設定
- 対象のUI部品(例: 虫眼鏡ボタン)を選択します。
- Identity Inspector (⌥⌘3) の下のほうにある Accessibility セクションを開きます。
Accessibility: Enabledにチェックを入れます。Labelに、音声で読み上げさせたい内容を分かりやすい単語で入力します(例:検索)。Traits(特性)で、それが何であるかをチェックします。ボタンならButtonです。Imageの場合はImageです。
コードでの設定
swift// 画像(UIImageView)をVoiceOverの対象にする profileImageView.isAccessibilityElement = true // 読み上げるテキストを設定する profileImageView.accessibilityLabel = "ユーザーのプロフィール画像" // 虫眼鏡ボタンの読み上げテキストを設定 searchButton.accessibilityLabel = "検索" // 任意: より詳細な説明(ヒント)を加える(長押し後などに読み上げられる) searchButton.accessibilityHint = "タップすると全ユーザーを検索できる画面に移動します"
これで、虫眼鏡ボタンをタップするとVoiceOverは「検索、ボタン」と正しく発話するようになります。
3. 複雑なカスタムビューの要素をグループ化する
Day 16などで作成した「ユーザーアイコン+名前+ツイート本文」が載ったカスタムセル(UITableViewCell)を考えてください。 デフォルトのままだと、ユーザーは「アイコンをタップして聞く」→「スワイプ」→「名前を聞く」→「スワイプ」→「本文を聞く」という、非常に煩わしい操作を強要されます。
これを解決するために、「セル全体を一つのAccessibility要素としてまとめ、連結した文章を読み上げる」配慮が必要です。
swift// CustomTweetCell.swift の awakeFromNib 等に記述 override func awakeFromNib() { super.awakeFromNib() // セル自体を一つのAccessibility要素として扱う self.isAccessibilityElement = true // 中に入っている個別の要素(Labelなど)はVoiceOverのフォーカスを外す userImageView.isAccessibilityElement = false userNameLabel.isAccessibilityElement = false tweetContentLabel.isAccessibilityElement = false } // データがセットされた時に、読み上げ用の連結文章を生成してセットする func configure(tweet: Tweet) { userNameLabel.text = tweet.userName tweetContentLabel.text = tweet.content // 💡 VoiceOver用に、人間が聞いて自然な文章を組み立てる self.accessibilityLabel = "\(tweet.userName)さんの投稿: \(tweet.content)" self.accessibilityTraits = .button // セルはタップできるのでボタン特性を持たせる }
これで、セルを1回触るだけで「S7r1n9yさんの投稿: こんにちは世界、ボタン」と一気に要約して読み上げてくれる、極めて使いやすいUIになります。
📝 今日のまとめ
- アプリをより多くの人に届けるため、VoiceOverへの配慮(Accessibility設計)はプロとして当然の責務 である。
- 文字のないアイコン画像やボタンには、必ず
accessibilityLabel(「検索」などの単語)を設定する。 - さらに詳しい説明が必要な場合は
accessibilityHintを付与する。 - 複数の情報がまとまったセルやViewは、全体を一つの
isAccessibilityElement = trueとし、個別の要素を束ねた自然な文章をaccessibilityLabelに設定してグループ化することで、UXが劇的に向上する。
アプリの成熟度が最高レベルに達しました。 明日の Day 29 では、「UIKitで作られた既存アプリ」に対して、Appleの最新UIフレームワークである「SwiftUI」の画面を部分的に埋め込んで共存させる、今後の実務で100%求められる橋渡し技術について解説します。
このシリーズの記事一覧
- 1. 完全に理解する Storyboard & UIKit (Day 1): 基礎概念と歴史
- 2. 完全に理解する Storyboard & UIKit (Day 2): XcodeでのStoryboardの基本操作
- 3. 完全に理解する Storyboard & UIKit (Day 3): UIViewControllerのライフサイクル
- 4. 完全に理解する Storyboard & UIKit (Day 4): Auto Layoutの基本原理
- 5. 完全に理解する Storyboard & UIKit (Day 5): Auto Layoutの複雑な制約の解決
- 6. 完全に理解する Storyboard & UIKit (Day 6): UIStackViewを使った効率的なレイアウト設計
- 7. 完全に理解する Storyboard & UIKit (Day 7): Size Classesによるレスポンシブデザイン
- 8. 完全に理解する Storyboard & UIKit (Day 8): Segueによる画面遷移とデータ渡し
- 9. 完全に理解する Storyboard & UIKit (Day 9): Navigation Controllerの活用
- 10. 完全に理解する Storyboard & UIKit (Day 10): Tab Bar Controllerの活用
- 11. 完全に理解する Storyboard & UIKit (Day 11): 基本的なUI部品(UILabel, UIButton, UITextField)
- 12. 完全に理解する Storyboard & UIKit (Day 12): UITextViewとキーボードハンドリング
- 13. 完全に理解する Storyboard & UIKit (Day 13): UIImageViewと画像リソース管理
- 14. 完全に理解する Storyboard & UIKit (Day 14): UIScrollViewとコンテンツのスクロール
- 15. 完全に理解する Storyboard & UIKit (Day 15): UITableViewの実装基礎
- 16. 完全に理解する Storyboard & UIKit (Day 16): UITableViewのカスタムセル作成
- 17. 完全に理解する Storyboard & UIKit (Day 17): UICollectionViewの実装基礎
- 18. 完全に理解する Storyboard & UIKit (Day 18): UICollectionViewのカスタムレイアウト
- 19. 完全に理解する Storyboard & UIKit (Day 19): Custom Viewの作成とStoryboardでの利用(@IBDesignable, @IBInspectable)
- 20. 完全に理解する Storyboard & UIKit (Day 20): アニメーションの実装(UIView Animation)
- 21. 完全に理解する Storyboard & UIKit (Day 21): Gesture Recognizerによるタッチ処理
- 22. 完全に理解する Storyboard & UIKit (Day 22): UIAlertControllerによるアラートとアクションシート
- 23. 完全に理解する Storyboard & UIKit (Day 23): UIDatePickerやUIPickerViewの実装
- 24. 完全に理解する Storyboard & UIKit (Day 24): Storyboard Referenceを用いたStoryboard分割
- 25. 完全に理解する Storyboard & UIKit (Day 25): XIBとStoryboardの使い分け・併用
- 26. 完全に理解する Storyboard & UIKit (Day 26): UIAppearanceによるアプリ全体の色・スタイル管理
- 27. 完全に理解する Storyboard & UIKit (Day 27): ダークモード対応とアセットカタログ
- 28. 完全に理解する Storyboard & UIKit (Day 28): Accessibility(VoiceOver対応など)のUI設計
- 29. 完全に理解する Storyboard & UIKit (Day 29): UIKitからSwiftUIへの移行 / UIKitでのSwiftUI利用
- 30. 完全に理解する Storyboard & UIKit (Day 30): 実践:1つのアプリをStoryboardとUIKitで完成させる