on
[RN] React Native Docs #6 : Inclusion
[RN] React Native Docs #6 : Inclusion
리액트 네이티브 스터디를 통해 공식문서를 번역하고 학습한 내용을 기록한 글입니다.
해당 게시글 내용은 공식문서 번역 내용 및 예제 실행이 가능하도록 제작한 앱, RNDOC 에서도 확인하실 수 있습니다.
접근성
Android와 iOS 모두 번들 스크린 리더인 VoiceOver (iOS), TalkBack (Android)과 같은 보조 기술과 앱을 통합하기 위한 API를 제공합니다.
Android와 iOS는 접근법이 약간 다르기 때문에, React Native 구현은 플랫폼에 따라 달라질 수 있습니다.
접근성 속성#
true 인 경우, 뷰가 접근성 엘리먼트임을 나타냅니다. 뷰가 접근성 엘리먼트일 때, 뷰는 자식 엘리먼트들을 선택 가능한 단일 컴포넌트로 그룹화합니다. 기본적으로는, 터치 가능한 모든 엘리먼트가 접근성 엘리먼트입니다.
Android에서, react-native 뷰를 위한 accessible={true} 속성은 네이티브의 focusable={true} 로 변환됩니다.
text one text two
뷰가 접근 가능으로 표시되면, VoiceOver 사용자가 자신이 어떤 엘리먼트를 선택했는지 알 수 있도록 뷰에 접근성 레이블을 설정하는 것이 좋습니다. VoiceOver는 사용자가 관련된 엘리먼트를 선택했을 때 이 문자열(접근성 레이블)을 읽어줍니다.
사용하려면 뷰, 텍스트, 또는 Touchable의 커스텀 문자열에 accessibilityLabel 속성을 설정해야 합니다.
Press me!
위 예제에서 TouchableOpacity 엘리먼트의 accessibilityLabel(접근성 레이블)은 "Press me!"가 기본값입니다. 이 레이블은 공백으로 구분된 모든 텍스트 노드 자식 엘리먼트들을 연결해 구성됩니다.
접근성 힌트는 사용자가 접근성 레이블만으로는 결과를 명확히 알 수 없는 동작을 수행할 때, 어떤 일이 발생할지 이해할 수 있도록 돕는 역할을 합니다.
사용하려면 뷰, 텍스트, 또는 Touchable의 커스텀 문자열에 accessibilityHint 속성을 설정하면 됩니다.
Back
위 예제에서 iOS의 VoiceOver는 사용자가 디바이스의 VoiceOver 환경설정에서 힌트를 사용가능하게 설정한 경우, 레이블을 읽은 후에 힌트를 읽습니다.
접근성 힌트의 가이드라인을 더 알아보려면 iOS 개발자 문서를 참고하세요.
위 예제에서 Android의 TalkBack은 레이블을 읽은 후에 힌트를 읽습니다. 현재 안드로이드에서는 힌트를 끌 수 없습니다.
화면 색상 반전은 밝기에 민감한 사람들의 눈을 더 편안하게 해주고, 색맹이 있는 사람들이 색을 더 쉽게 구별할 수 있게 해주며, 시력이 낮은 사람들이 쉽게 알아볼 수 있도록 해주는 접근성 기능입니다. 그러나 간혹 반전시키고 싶지 않은 사진과 같은 뷰들도 있습니다. 이러한 경우에는accessibilityIgnoresInvertColors 속성을 false로 설정해서 특정한 뷰의 색상이 반전되지 않도록 할 수 있습니다.
컴포넌트가 동적으로 변화할 때, TalkBack이 유저에게 변화의 끝을 알리려면 accessibilityLiveRegion 속성을 사용하면 됩니다. 이 속성은none, polite, assertive 등으로 설정될 수 있습니다.
none 접근성 서비스는 이 뷰에 대한 변경사항을 알리면 안 됩니다.
접근성 서비스는 이 뷰에 대한 변경사항을 알리면 안 됩니다. polite 접근성 서비스는 이 뷰에 대한 변경사항을 알려야 합니다.
접근성 서비스는 이 뷰에 대한 변경사항을 알려야 합니다. assertive 접근성 서비스는 진행중인 알림을 중단하고 이 뷰의 변경사항을 즉시 알려야 합니다.
Click me Clicked {count} times
위 예제에서 addOne 메소드는 state 변수 count 를 변경합니다. accessibilityLiveRegion="polite"로 설정되어 있기 때문에, 최종 사용자가 TouchableWithoutFeedback을 클릭하면 TalkBack이 텍스트 뷰의 텍스트를 읽습니다.
accessibilityRole 은 보조 기술의 사용자에게 컴포넌트의 목적을 전달합니다.
accessibilityRole은 다음 중 하나로 설정될 수 있습니다.
adjustable 엘리먼트가 "조정"될 수 있을 때 사용됩니다. (예: 슬라이더)
엘리먼트가 "조정"될 수 있을 때 사용됩니다. (예: 슬라이더) alert 엘리먼트가 사용자에게 표시할 중요한 텍스트를 포함하고 있을 때 사용됩니다.
엘리먼트가 사용자에게 표시할 중요한 텍스트를 포함하고 있을 때 사용됩니다. button 엘리먼트를 버튼으로 취급해야할 때 사용됩니다.
엘리먼트를 버튼으로 취급해야할 때 사용됩니다. checkbox 엘리먼트가 체크된, 체크가 해제된, 또는 혼합된 상태를 가지는 체크박스를 나타낼 때 사용됩니다.
엘리먼트가 체크된, 체크가 해제된, 또는 혼합된 상태를 가지는 체크박스를 나타낼 때 사용됩니다. combobox 사용자가 여러 개의 항목 중에 선택할 수 있도록 하는 콤보 상자를 나타낼 때 사용됩니다.
사용자가 여러 개의 항목 중에 선택할 수 있도록 하는 콤보 상자를 나타낼 때 사용됩니다. header 엘리먼트가 콘텐츠 영역에서 헤더 역할을 할 때 사용됩니다. (예: 네비게이션 바의 타이틀)
엘리먼트가 콘텐츠 영역에서 헤더 역할을 할 때 사용됩니다. (예: 네비게이션 바의 타이틀) image 엘리먼트가 이미지로 취급될 때 사용됩니다. 버튼 또는 링크 등과 결합될 수 있습니다.
엘리먼트가 이미지로 취급될 때 사용됩니다. 버튼 또는 링크 등과 결합될 수 있습니다. imagebutton 엘리먼트가 이미지인 동시에 버튼으로 취급될 때 사용됩니다.
엘리먼트가 이미지인 동시에 버튼으로 취급될 때 사용됩니다. keyboardkey 엘리먼트가 키보드의 키 역할을 할 때 사용됩니다.
엘리먼트가 키보드의 키 역할을 할 때 사용됩니다. link 엘리먼트가 링크로 취급되어야 할 때 사용됩니다.
엘리먼트가 링크로 취급되어야 할 때 사용됩니다. menu 컴포넌트가 선택 메뉴일 때 사용됩니다.
컴포넌트가 선택 메뉴일 때 사용됩니다. menubar 컴포넌트가 여러 메뉴의 컨테이너일 때 사용됩니다.
컴포넌트가 여러 메뉴의 컨테이너일 때 사용됩니다. menuitem 메뉴 안의 항목을 나타낼 때 사용됩니다.
메뉴 안의 항목을 나타낼 때 사용됩니다. none 엘리먼트에 아무런 역할이 없을 때 사용됩니다.
엘리먼트에 아무런 역할이 없을 때 사용됩니다. progressbar 작업 진행상황을 보여주는 컴포넌트를 나타내는 데 사용됩니다.
작업 진행상황을 보여주는 컴포넌트를 나타내는 데 사용됩니다. radio 라디오 버튼을 나타내는 데 사용됩니다.
라디오 버튼을 나타내는 데 사용됩니다. radiogroup 라디오 버튼 그룹을 나타내는 데 사용됩니다.
라디오 버튼 그룹을 나타내는 데 사용됩니다. scrollbar 스크롤바를 나타낼 때 사용됩니다.
스크롤바를 나타낼 때 사용됩니다. search 텍스트 필드 엘리먼트가 동시에 검색 필드로 취급되어야할 때 사용됩니다.
텍스트 필드 엘리먼트가 동시에 검색 필드로 취급되어야할 때 사용됩니다. spinbutton 선택 목록을 여는 버튼을 나타낼 때 사용됩니다.
선택 목록을 여는 버튼을 나타낼 때 사용됩니다. summary 앱이 처음 실행될 때 앱의 현재 상태에 대한 빠른 요약을 제공하는 데에 엘리먼트를 사용할 수 있는 경우 사용됩니다.
앱이 처음 실행될 때 앱의 현재 상태에 대한 빠른 요약을 제공하는 데에 엘리먼트를 사용할 수 있는 경우 사용됩니다. switch 켜고 끌 수 있는 스위치를 나타내는 데 사용됩니다.
켜고 끌 수 있는 스위치를 나타내는 데 사용됩니다. tab 탭을 나타내는 데 사용됩니다.
탭을 나타내는 데 사용됩니다. tablist 탭 리스트를 나타내는 데 사용됩니다.
탭 리스트를 나타내는 데 사용됩니다. text 엘리먼트가 변하지 않는 정적 텍스트로 취급되어야할 때 사용됩니다.
엘리먼트가 변하지 않는 정적 텍스트로 취급되어야할 때 사용됩니다. timer 타이머를 나타낼 때 사용합니다.
타이머를 나타낼 때 사용합니다. toolbar 툴바/도구모음(작업 단추 또는 컴포넌트들의 컨테이너)을 나타낼 때 사용됩니다.
보조기술 사용자에게 컴포넌트의 현재 state를 설명합니다.
accessibilityState 는 객체입니다. 다음 필드들을 포함하고 있습니다.
*(여기에 테이블 삽입 / https://reactnative.dev/docs/accessibility 참고) **
사용하려면 특정한 정의가 있는 객체에 accessibilityState 를 설정합니다.
컴포넌트의 현재 값을 나타냅니다. 컴포넌트의 값에 대한 설명 텍스트일 수도 있고, 슬라이더나 프로그레스 바와 같은 범위 기반 컴포넌트의 경우 범위 정보를 포함합니다. (최소값, 현재값, 최대값)
accessibilityValue is an object. It contains the following fields:
accessibilityValue는 객체이며 다음 필드들을 포함합니다.
*(여기에 테이블 삽입 / https://reactnative.dev/docs/accessibility 참고) **
accessibilityViewIsModal : iOS#
VoiceOver가 수신자의 형제 뷰 안의 엘리먼트들을 무시해야하는지 여부를 나타내는 Boolean 값입니다.
예를 들어, 하나의 윈도우가 형제 뷰 A와 B를 포함하고 있을 때, 뷰 B의accessibilityViewIsModal 속성을 true로 설정하면 뷰 A의 엘리먼트들이 무시됩니다. 반면에, 뷰 B가 자식 뷰 C를 포함하고 있는 상태에서 뷰 C의 accessibilityViewIsModal 속성을 true로 설정하면 VoiceOver는 뷰 A의 엘리먼트들을 무시하지 않습니다.
accessibilityElementsHidden : iOS#
접근성 엘리먼트 내부에 있는 접근성 엘리먼트가 숨겨진 상태인지 여부를 나타내는 Boolean 값입니다.
예를 들어 형제 뷰 A와 B를 포함하고 있는 윈도우에서 뷰 B의 accessibilityElementsHidden 를 true로 설정하면, VoiceOver가 뷰 B의 엘리먼트들을 무시하게 만듭니다. Android의 importantForAccessibility="no-hide-descendants" 속성과 비슷합니다.
importantForAccessibility : Android#
부모가 동일한 두 개의 겹치는 UI 컴포넌트의 경우, 기본 접근성 포커스는 예측할 수 없는 동작을 가질 수 있습니다. importantForAccessibility 속성은 뷰가 접근성 이벤트를 발생시키는지 여부와, 이벤트를 접근성 서비스에 보고하는지 여부를 제어해 문제를 해결합니다. 이 속성은 auto, yes, no, no-hide-descendants 로 설정할 수 있습니다. (no-hide-descendants는 접근성 서비스가 컴포넌트와 컴포넌트의 모든 자식 엘리먼트를 무시하도록 강제합니다. )
First layout Second layout
위 예제에서, yellow 레이아웃과 그 하위 항목들은 TalkBack 및 기타 모든 접근성 서비스에서 완전히 보이지 않게 됩니다. 따라서 TalkBack을 혼동시키지 않고 동일한 부모의 겹치는 뷰를 사용할 수 있습니다.
onAccessibilityEscape : iOS#
두 손가락으로 Z 모양의 "탈출(escape)" 제스쳐를 할 때 호출되는 사용자 정의 함수에 이 속성을 할당합니다. 이스케이프 함수는 사용자 인터페이스에서 뒤 쪽 계층으로 이동해야합니다. 이것은 네비게이션 계층에서 위로 또는 뒤로 이동하거나, 모달 사용자 인터페이스를 해제하는 것을 의미합니다. 만약 선택된 엘리먼트가 onAccessibilityEscape 함수를 가지고 있지 않다면, 시스템은 해당 함수를 가진 뷰를 찾을 때까지 뷰 계층 구조를 탐색하거나, 이 함수를 가진 뷰를 찾을 수 없다고 표시합니다.
이 속성을 사용해서, 접근성 엘리먼트가 선택된 상태에서 두 번 눌러 활성화 시켰을 때 호출될 사용자 정의 함수를 할당합니다.
onMagicTap : iOS#
두 손가락으로 두 번 탭하는 "매직 탭" 제스쳐를 수행했을 때 호출되는 사용자 정의 함수에 이 속성을 할당합니다. 매직 탭 함수는 사용자가 컴포넌트에 대해 실행할만한 가장 관련성있는 작업을 수행해야 합니다. 아이폰의 전화 앱에서는 매직 탭으로 전화를 받거나, 통화를 종료할 수 있습니다. 만약 선택된 엘리먼트에onMagicTap 함수가 없는 경우, 시스템은 onMagicTap 함수를 가진 뷰를 찾을 때까지 뷰 계층 구조를 올라가며 탐색합니다.
접근성 작업#
보조 기술은 접근성 작업을 통해 컴포넌트의 동작을 프로그래밍적으로 호출할 수 있습니다. 접근성 작업을 지원하려면 컴포넌트는 다음 두 가지를 수행해야 합니다.
accessibilityActions 속성을 통해 지원하는 작업 목록을 정의해야 합니다.
작업 요청을 처리할 onAccessibilityAction 함수를 구현해야 합니다.
accessibilityActions 속성은 작업 객체 목록을 포함해야 합니다. 각 작업 객체에는 다음 필드들이 포함되어 있어야 합니다.
*(여기에 테이블 삽입 / https://reactnative.dev/docs/accessibility 참고) **
작업은 버튼 클릭이나 슬라이더 조정과 같은 표준 작업을 나타내거나, 이메일 메세지 삭제와 같이 특정한 컴포넌트에만 지정한 사용자 정의 작업을 나타냅니다. name 필드는 표준 작업과 사용자 정의 작업 둘 다에서 필수이고, label 은 표준 작업의 경우에는 선택 사항입니다.
표준 작업에 대한 지원을 추가할 때, name은 다음 중 하나여야합니다.
'magicTap' - iOS 전용 - VoiceOver가 컴포넌트에, 혹은 컴포넌트의 안에 포커스를 두고 있을 때, 사용자가 두 손가락으로 두 번 탭했습니다.
'escape' - iOS 전용 - VoiceOver가 컴포넌트나 컴포넌트의 안에 포커스를 두고 있을 때, 사용자가 두 손가락으로 스크럽 제스쳐(왼쪽, 오른쪽, 왼쪽)를 수행했습니다.
'activate' - 컴포넌트를 활성화합니다. 일반적으로, 사용자가 보조 기술을 사용하지 않는 컴포넌트를 클릭하거나 터치했을 때와 동일한 작업이 수행되어야 합니다. 스크린 리더 사용자가 컴포넌트를 두 번 탭하면 생성됩니다.
'increment' - 조정 가능한 컴포넌트를 늘립니다. iOS에서 VoiceOver는 컴포넌트가 'adjustable'의 역할을 가지고 있고 사용자가 포커스를 컴포넌트에 둔 채로 위로 스와이프할 때 이 작업을 수행합니다. Android에서 TalkBack은 사용자가 컴포넌트에 접근성 포커스를 두고 볼륨 업 버튼을 눌렀을 때 이 작업을 수행합니다.
'decrement' - 조정 가능한 컴포넌트를 줄입니다. iOS에서 VoiceOver는 컴포넌트가 'adjustable' 역할을 가지고 있고 사용자가 포커스를 컴포넌트에 둔 채로 아래로 스와이프할 때 이 작업을 수행합니다. Android에서 TalkBack은 사용자가 컴포넌트에 접근성 포커스를 두고 볼륨 다운 버튼을 눌렀을 때 이 작업을 수행합니다.
'longpress' - Android 전용 - 이 작업은 사용자가 컴포넌트에 접근성 포커스를 두고, 두 번 탭 하며 한 손가락을 스크린 위에 올려두고 있을 때 실행됩니다. 일반적으로, 이 작업은 사용자가 보조 기술을 사용하지 않고 컴포넌트를 한 손가락으로 누르고 있을 때와 동일한 작업을 수행해야 합니다.
label 필드는 표준 작업의 경우 선택사항이며, 보조기술에서는 사용되지 않을 때가 많습니다. 사용자 정의 작업에서 label 은 사용자에게 보여줄 작업에 대한 설명이 포함된, 로컬화된 문자열입니다.
작업 요청을 처리하려면, 컴포넌트는 onAccessibilityAction 함수를 구현해야 합니다. 이 함수가 받는 유일한 매개변수는 수행할 작업의 이름을 포함한 이벤트입니다. 아래의 RNTester 예시는 여러 사용자 정의 작업을 정의하고 처리하는 컴포넌트를 생성하는 방법을 보여줍니다.
{ switch (event.nativeEvent.actionName) { case 'cut': Alert.alert('Alert', 'cut action success'); break; case 'copy': Alert.alert('Alert', 'copy action success'); break; case 'paste': Alert.alert('Alert', 'paste action success'); break; } }} />
스크린 리더가 활성화되었는지 확인하기#
AccessibilityInfo API를 사용하면 스크린 리더가 활성화되었는지 여부를 확인할 수 있습니다. 자세한 내용은 AccessibilityInfo documentation를 참조하세요.
접근성 이벤트 보내기 (Android)#
UI 컴포넌트에서 접근성 이벤트를 발생시키는 것이 유용할 때가 있습니다. (예: 사용자 정의 뷰가 화면에 표시되거나 뷰에 접근성 포커스를 설정하는 경우). 네이티브 UIManager 모듈은 이를 위해 sendAccessibilityEvent 메소드를 expose한합니다. 이 메소드는 두 개의 매개변수(뷰 태그와 이벤트 타입)를 받습니다. 지원되는 이벤트 타입은 typeWindowStateChanged, typeViewFocused, typeViewClicked이 있습니다.
import { Platform, UIManager, findNodeHandle } from 'react-native'; if (Platform.OS === 'android') { UIManager.sendAccessibilityEvent( findNodeHandle(this), UIManager.AccessibilityEventTypes.typeViewFocused ); }
TalkBack 지원 테스트 (Android)#
TalkBack을 활성화하려면, Android 기기 또는 애뮬레이터의 환경설정으로 이동합니다. 접근성을 선택한 다음 TalkBack을 선택합니다. "서비스 사용(Use service)" 스위치를 토글해서 활성화 또는 비활성화합니다.
참고) 안드로이드 애뮬레이터에는 기본적으로 TalkBack이 설치되어 있지 않습니다. 설치하려면 다음 지침을 따르세요.
여기에서 TalkBack 파일을 다운로드합니다. 다운로드한 .apk 파일을 애뮬레이터로 드래그합니다.
볼륨 단축 키를 사용해 TalkBack을 활성화/비활성화할 수 있습니다. 볼륨 단축 키를 켜려면 설정 앱으로 이동한 다음 접근성을 선택해 상단의 볼륨 단축 키를 활성화합니다.
볼륨 단축 키를 사용하려면 두 볼륨 키를 3초간 눌러 접근성 도구를 시작합니다.
또한 원하는 경우 커맨드라인에서 다음 명령을 통해 TalkBack을 활성화 또는 비활성화할 수 있습니다.
# 비활성화 adb shell settings put secure enabled_accessibility_services com.android.talkback/com.google.android.marvin.talkback.TalkBackService # 활성화 adb shell settings put secure enabled_accessibility_services com.google.android.marvin.talkback/com.google.android.marvin.talkback.TalkBackService
VoiceOver 지원 테스트(iOS)#
VoiceOver를 활성화하려면, iOS 디바이스의 설정 앱으로 가서 일반(General)을 선택한 다음 접근성(Accessibility)을 선택합니다. 여기에서 텍스트 굵게 하기, 대비 증가 및 VoiceOver와 같이 디바이스를 더 유용하게 만들 수 있는 많은 툴들을 찾을 수 있습니다.
VoiceOver를 활성화하려면 "Vision" 아래의 VoiceOver를 누르고 상단에 표시되는 스위치를 켜면 됩니다.
접근성 설정의 맨 아래에 "접근성 바로가기"가 있습니다. 이 기능을 사용하면, 홈 버튼을 세 번 클릭하여 VoiceOver를 활성화/비활성화할 수 있습니다.
추가 자료#
from http://leejiwonn.tistory.com/63 by ccl(A) rewrite - 2021-12-07 01:27:02