VoiceOver: iOS에서의 제스처 제어 및 기능

저자: IT Sectr 게시일: 2026-05-15 읽는 시간: 8 분

VoiceOver는 Apple의 내장 스크린 리더로, 인터페이스의 모든 요소를 음성으로 읽어주고 제스처를 통해 기기를 제어할 수 있습니다. 이 기술은 iOS, iPadOS 및 macOS에 시스템 수준으로 내장되어 있으며 추가 소프트웨어 설치가 필요 없습니다. Apple Accessibility (2025)에 따르면 VoiceOver는 40개 이상의 언어를 지원하며 전 세계 수백만 명의 시각 장애인이 사용하고 있습니다.

핵심 요약

  • VoiceOver는 iOS, iPadOS 및 macOS에 내장된 스크린 리더로, 제스처와 음성으로 제어
  • VoiceOver 로터가 탐색 모드를 전환: 단어, 문자, 제목, 링크
  • 제스처에는 탭(읽기), 스와이프(이동), 더블 탭(활성화) 포함
  • 개발자는 UIAccessibility 및 Accessibility Label을 통해 접근성 구성
  • VoiceOver는 동적 텍스트 및 점자 디스플레이와 통합

VoiceOver란?

VoiceOver는 Apple 운영 체제에 내장된 스크린 리더입니다. 시각 장애인을 위해 설계되었으며 시각적 접촉 없이 기기와 완전히 상호 작용할 수 있습니다. VoiceOver는 버튼, 링크, 텍스트, 이미지, 알림 및 시스템 요소 등 인터페이스의 모든 요소를 음성으로 읽어줍니다.

이 기술은 2005년 macOS용으로 처음 도입되었으며, iOS에는 2009년 iPhone 3GS와 함께 등장했습니다. 그 이후로 VoiceOver는 Apple 생태계의 필수적인 부분이자 플랫폼 접근성을 지지하는 주요 논거 중 하나가 되었습니다. VoiceOver는 시스템 수준에 내장되어 있어 개발자의 추가 통합 없이 모든 애플리케이션에서 작동하지만, 읽기 품질은 애플리케이션이 iOS 접근성 API를 얼마나 잘 활용하는지에 직접적으로 의존합니다.

VoiceOver는 자연스러운 음성 합성으로 40개 이상의 언어를 지원하며 지역별 음성 설정에 적응합니다. iOS에서 VoiceOver는 한국어 및 기타 여러 언어에 대해 Siri 음성 엔진을 사용하여 구두점과 문맥에 따라 가장 자연스러운 발음과 정확한 억양을 보장합니다.

VoiceOver 작동 방식

VoiceOver는 터치 이벤트를 가로채서 표준 iOS 입력과 다르게 해석합니다. 사용자가 화면을 터치하면 VoiceOver는 손가락 아래의 요소를 활성화하지 않고 먼저 읽어줍니다. 더블 탭 후에만 요소가 활성화됩니다. 이 중요한 차이점으로 인해 시각 장애인은 실수로 클릭할 위험 없이 인터페이스를 탐색할 수 있습니다.

읽기 순서 및 탐색

VoiceOver는 인터페이스 요소를 논리적 순서(왼쪽에서 오른쪽, 위에서 아래)로 읽습니다. 읽기 순서는 iOS 뷰 계층 구조에서 상속되지만, 개발자는 복잡한 레이아웃의 경우 accessibilityElements 속성을 통해 변경할 수 있습니다. 사용자는 오른쪽 스와이프(다음)와 왼쪽 스와이프(이전)로 요소 간에 이동하거나 특정 요소를 터치하여 읽게 할 수 있습니다.

이동할 때마다 VoiceOver는 요소 유형(버튼, 링크, 제목), 이름(accessibilityLabel), 상태(선택됨, 비활성화됨) 및 힌트(accessibilityHint)를 말합니다. 요소에 값이 있는 경우(예: 볼륨 슬라이더), VoiceOver는 그 값도 읽어줍니다. 접근성 특성(UIAccessibilityTraits)은 요소가 버튼, 스위치, 검색 필드 또는 키보드 키인지 여부 등 요소의 동작에 대해 사용자에게 추가로 알려줍니다.

VoiceOver 로터

로터는 VoiceOver 탐색 모드를 전환하는 가상 조정 다이얼입니다. 사용자는 두 손가락으로 로터를 회전(볼륨 노브처럼)시키고 단어, 문자, 제목, 링크, 진입점, 테이블 행 등의 모드를 선택합니다. 제목 모드는 웹 페이지와 애플리케이션에서 H1-H6 간에 빠르게 전환할 수 있게 하며, 문자 모드는 텍스트를 글자 단위로 읽어주어 양식 작성이나 확인 코드 입력 시 유용합니다.

개발자는 UIAccessibilityCustomRotor API를 통해 로터에 사용자 정의 모드를 추가할 수 있습니다. 예를 들어, 메모 애플리케이션에서 “즐겨찾는 메모” 또는 “최근 변경 사항” 로터를 추가할 수 있습니다. 사용자 정의 로터는 특정 애플리케이션에서 탐색을 크게 가속화하며 iOS 접근성의 모범 사례로 간주됩니다.

VoiceOver 제스처 제어

VoiceOver는 표준 iOS 제스처와 일치하지 않는 자체 제스처 세트를 사용합니다. 대부분의 제스처는 한 손가락 대신 세 손가락으로 수행됩니다. 이는 일반적인 조작과의 충돌을 방지하고 VoiceOver가 표준 입력과 동시에 작동할 수 있게 합니다.

동작제스처결과
요소 읽기1손가락 탭요소 이름 말하기
활성화더블 탭버튼 또는 링크 누르기
다음 요소오른쪽으로 스와이프다음으로 이동
이전 요소왼쪽으로 스와이프이전으로 돌아가기
스크롤3손가락 스와이프목록 또는 페이지 스크롤
로터2손가락 회전탐색 모드 변경

더블 탭 제스처는 VoiceOver에서 요소를 활성화하는 기본 방법입니다. 요소에 특별한 동작(예: 드래그)이 필요한 경우 VoiceOver는 “탭 — 더블 탭 및 유지” 시퀀스를 사용하여 이동 모드로 진입합니다. 이를 통해 화면을 보지 않고 드래그 앤 드롭과 같은 복잡한 제스처를 수행할 수 있습니다. VoiceOver는 동작 취소를 위한 “두 손가락 더블 탭”과 스크린 커튼 켜기/끄기를 위한 “트리플 탭” 제스처도 지원합니다.

모바일 개발에서의 VoiceOver

iOS 애플리케이션 개발자는 UIAccessibility API를 통해 VoiceOver와의 상호 작용을 크게 개선할 수 있습니다. 기본 접근성 설정은 Interface Builder(Identity Inspector → Accessibility)에서 추가되지만, 복잡한 인터페이스는 코드에서 프로그래밍 방식으로 구성해야 합니다.

접근성 레이블 및 특성

accessibilityLabel 속성은 VoiceOver가 요소에 대해 말하는 텍스트를 설정합니다. 레이블이 설정되지 않은 경우 VoiceOver는 버튼 텍스트 또는 텍스트 필드 플레이스홀더를 사용합니다. 텍스트가 없는 요소(아이콘, 사용자 정의 뷰)에는 레이블이 필수입니다. accessibilityTraits 속성은 요소 유형(버튼, 제목, 스위치, 검색 필드, 키보드 키, 값 변경, 링크 등)을 정의합니다.

swift
let profileButton = UIButton(type: .custom)
profileButton.setImage(UIImage(named: "avatar"), for: .normal)
profileButton.isAccessibilityElement = true
profileButton.accessibilityLabel = "사용자 프로필"
profileButton.accessibilityTraits = .button
profileButton.accessibilityHint = "프로필 설정 화면 열기"

isAccessibilityElement 플래그는 사용자 정의 뷰에 대한 VoiceOver 지원을 활성화합니다. 기본적으로 표준 요소(UIButton, UILabel, UITextField)에 대해서만 true입니다. accessibilityHint 매개변수는 힌트를 추가합니다. 사용자가 요소에 머무르면 VoiceOver가 일시 중지 후 힌트를 읽어줍니다. 힌트는 “설정 화면 열기”처럼 동작의 결과를 설명해야 하며 “열려면 누르세요”와 같은 지시사항이 아니어야 합니다.

그룹화 및 요소 순서

요소의 논리적 그룹이 시각적 순서와 일치하지 않는 복잡한 화면의 경우 accessibilityElements를 사용합니다. 이는 읽기 순서를 설정하는 배열입니다. 예를 들어, 상품 카드에는 이미지, 이름, 가격 및 “장바구니에 추가” 버튼이 포함됩니다. 이러한 요소가 뷰 계층 구조에 무질서하게 배치된 경우 accessibilityElements가 VoiceOver의 올바른 순서를 설정합니다.

swift
let productCard = UIView()
let productImage = UIImageView()
let productName = UILabel()
let productPrice = UILabel()
let addToCartButton = UIButton()

productCard.accessibilityElements = [
    productImage, productName, productPrice, addToCartButton
]

여러 요소를 하나의 접근 가능한 요소로 결합하려면 UIAccessibilityContainer 또는 터치 영역을 재정의하는 accessibilityFrame을 사용합니다. 이는 테이블 셀에 여러 UI 구성 요소가 포함되어 있지만 논리적으로 하나의 요소를 나타내는 경우에 유용합니다. VoiceOver는 셀 전체를 한 번에 읽어야 하며 내용을 개별적으로 반복해서는 안 됩니다.

VoiceOver 접근성 설정

VoiceOver의 올바른 접근성 설정에는 의미론적 마크업, 동적 업데이트, 사용자 정의 요소 처리 및 실제 스크린 리더로 테스트 등 여러 측면에 주의가 필요합니다.

SwiftUI의 의미론적 마크업

SwiftUI에서는 .accessibilityLabel(), .accessibilityValue(), .accessibilityHint() 및 .accessibilityAddTraits() 수정자를 통해 접근성을 구성합니다. SwiftUI는 표준 요소에서 접근성을 자동으로 상속하지만 사용자 정의 구성 요소에는 명시적 구성이 필요합니다. 예를 들어, 사용자 정의 슬라이더는 VoiceOver에 값과 변경 형식을 알려야 합니다.

swift
Slider(value: $volume, in: 0...100)
    .accessibilityLabel("음량")
    .accessibilityValue(
        Text("\(Int(volume)) 퍼센트")
    )
    .accessibilityAddTraits(.adjustsAudioForAccessibility)
    .accessibilityAdjustableAction { direction in
        switch direction {
        case .increment: volume = min(volume + 5, 100)
        case .decrement: volume = max(volume - 5, 0)
        }
    }

accessibilityAdjustableAction 수정자는 VoiceOver 제스처로 값을 변경하는 기능을 추가합니다(위로 스와이프 — 증가, 아래로 스와이프 — 감소). 이 수정자가 없으면 슬라이더는 스크린 리더 제어에 접근할 수 없게 됩니다. 사용자 정의 스테퍼, 피커 및 값을 변경하는 기타 요소에도 유사한 구성이 필요합니다.

동적 업데이트 및 알림

화면의 콘텐츠가 동적으로 변경될 때(알림 도착, 로딩 상태 업데이트, 가격 변경), VoiceOver는 UIAccessibility.post를 통해 알림을 받아야 합니다. 이 호출이 없으면 스크린 리더가 변경 사항을 알지 못하며 사용자는 중요한 정보를 놓치게 됩니다. SwiftUI의 경우 .accessibilityAnnouncement() 수정자를 사용합니다.

swift
UIAccessibility.post(
    notification: .announcement,
    argument: "가격이 20퍼센트 인하되었습니다"
)

// SwiftUI
Text("가격이 업데이트되었습니다")
    .accessibilityAnnouncement(Text("20% 할인"))

VoiceOver 알림은 신중하게 사용해야 합니다. 과도한 알림은 사용자를 귀찮게 하고, 부재 시에는 애플리케이션에 접근할 수 없게 됩니다. 최적의 전략은 사용자의 현재 작업 흐름에 영향을 미치는 변경 사항(장바구니 업데이트, 로딩 상태, 양식 유효성 검사 오류, 채팅 알림)만 알리는 것입니다. 백그라운드 변경 사항(패널 시간, 환율)은 알림이 필요하지 않습니다. 사용자는 필요할 때 직접 확인합니다.

VoiceOver 테스트는 스크린 리더를 켠 실제 기기 또는 Accessibility Inspector 옵션이 있는 iOS 시뮬레이터를 통해 수행됩니다. 시각적 제어 없이 전체 사용 시나리오(등록 완료, 주문, 검색으로 제품 찾기)를 테스트하는 것이 중요합니다. 시각적 피드백 없이 탐색할 수 있다면 VoiceOver가 올바르게 구성된 것입니다.

자주 묻는 질문

iPhone에서 VoiceOver를 켜는 방법

설정 → 손쉬운 사용 → VoiceOver. 스위치를 켭니다. 빠른 활성화를 위해 측면 버튼(iPhone X 이상) 또는 홈 버튼을 삼중 클릭합니다. Siri에게 “VoiceOver 켜줘”라고 말하여 활성화할 수도 있습니다.

VoiceOver와 TalkBack의 차이점

VoiceOver는 iOS용 Apple의 스크린 리더이고, TalkBack은 Android용 Google의 스크린 리더입니다. 작동 원리는 동일합니다. 터치로 읽고 더블 탭으로 활성화합니다. 차이는 제스처, 로터 설정 및 생태계 통합에 있습니다. VoiceOver가 iCloud 및 Apple Pay와 더 깊게 통합되어 있습니다.

내 애플리케이션에 VoiceOver를 설정하는 방법

UIAccessibility API를 사용합니다. 모든 요소에 accessibilityLabel, 요소 유형에 accessibilityTraits, 힌트에 accessibilityHint를 설정합니다. SwiftUI에서는 .accessibilityLabel() 및 .accessibilityAddTraits() 수정자를 사용합니다. VoiceOver를 켠 상태에서 애플리케이션을 테스트합니다.

VoiceOver의 로터란?

로터는 두 손가락 회전으로 전환하는 탐색 모드입니다. 제목, 문자, 단어, 링크 또는 진입점 중 무엇으로 요소 간을 이동할지 결정합니다. 개발자는 UIAccessibilityCustomRotor를 통해 자신만의 모드를 추가할 수 있습니다.

VoiceOver가 내 사용자 정의 요소를 읽지 않는 이유

사용자 정의 UIView의 경우 isAccessibilityElement = true를 설정하고 accessibilityLabel을 제공해야 합니다. 요소가 여러 하위 뷰로 구성된 경우 accessibilityElements를 사용하여 읽기 순서를 설정하거나 컨테이너로 결합합니다.

요약

  • VoiceOver는 iOS, iPadOS 및 macOS용 Apple 내장 스크린 리더로 음성 제스처 제어 지원
  • 로터가 탐색 모드 전환: 제목, 문자, 단어, 링크 및 사용자 정의 모드
  • VoiceOver 제스처: 탭 — 읽기, 더블 탭 — 활성화, 스와이프 — 이동
  • 개발 UIAccessibility API를 통해: label, traits, hint, 사용자 정의 로터 및 동적 알림
  • SwiftUI는 .accessibilityLabel(), .accessibilityAddTraits() 및 .accessibilityAdjustableAction() 수정자 제공
  • 동적 업데이트는 VoiceOver에 알리기 위해 UIAccessibility.post 호출 필요
  • 테스트는 시각적 제어 없이 VoiceOver를 켠 실제 기기에서 필수

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기