스크린 리더(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입니다. API, 제스처 및 기능이 다르지만 공통 원칙은 접근성 트리 읽기 및 제스처 제어입니다.
VoiceOver는 Apple의 스크린 리더로, iOS, iPadOS 및 macOS에 내장되어 있습니다. 요소에 대한 정보를 얻기 위해 UIAccessibility API를 사용하고 탐색 모드 전환을 위한 로터를 지원합니다. VoiceOver는 iCloud(기기 간 설정 동기화), Apple Pay(Touch ID 또는 Face ID를 통한 결제 확인) 및 동적 텍스트(글꼴이 사용자 설정에 적응)와 통합되어 있습니다.
VoiceOver의 제스처는 TalkBack과 다릅니다: 두 손가락 회전(로터), Screen Curtain을 위한 세 번 탭, 작업 취소를 위한 두 손가락 두 번 탭을 사용합니다. 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를 사용하고 탐색에 로터(두 손가락 회전)를 사용합니다. TalkBack은 Android에서 AccessibilityService를 사용하고 L자형 스와이프를 통한 전역 메뉴를 사용합니다. 작동 원리(접근성 트리 탐색)는 동일합니다.
스크린 리더는 이미지를 ‘볼’ 수 없습니다. 개발자가 contentDescription(Android) 또는 accessibilityLabel(iOS)을 통해 제공하는 텍스트 설명을 읽습니다. 설명이 설정되지 않은 경우 스크린 리더는 파일 이름을 읽거나 단순히 ‘이미지’라고 말할 수 있습니다. 이는 사용자에게 유용하지 않습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.