[iOS] VoiceOver에서 customAction을 읽지 않을 때

기본 언어 설정에 따라 음성 송출이 되지 않을 수 있다구요?

naljin
9 min readJun 16, 2021

UIAccessibilityCustomAction 이란?

iOS의 accessibility에서 customAction 을 사용한다는게 어떤 의미인지 알고 계시나요?

Voice Over를 켜서 element 들을 탐색할때, 종종 마지막에 “동작을 사용할 수 있습니다” 라는 코멘트가 나옵니다. 이때 스와이프 업 / 다운을 통해 해당 element에 대한 특정 동작을 수행할 수 있습니다.

해당 예시는 기본 시계 앱에서 찾아볼 수 있는데요

위의 화면에서 저는 row를 삭제하기 위해 오른쪽에서 왼쪽으로 (<-) 스와이프를 한 후, 삭제 버튼을 누릅니다.

하지만 voice over 를 켠 후, 같은 동작을 하면 어떻게 될까요? voice over context에서 오른쪽에서 왼쪽으로 (<-) 스와이프 동작은 이전 element를 찾는다는 의미이기 때문에, “세계 시계”로 focus 됩니다.

오른쪽에서 왼쪽으로 스와이프

그렇다면 voice over를 켠 상태에서는, 어떻게 row를 삭제 할까요?

row가 focus 될 때 마지막에 voice over가 “동작을 사용할 수 있습니다” 라는 텍스트를 읽어주기 때문에, 우선 이를 통해 해당 element에 대한 추가 동작을 할 수 있음을 인지할 수 있습니다. 이제 동작을 사용하기 위해 swipe up/down을 해봅시다.

(+ “동작을 사용할 수 있습니다” 를 언젠가부터 읽어주지 않는다. — VoiceOver: “actions available” not announced anymore in iOS 13.)

위에서 아래로 스와이프

“삭제” 텍스트를 읽어주네요. 이 상태에서 더블 탭을 하면 해당 row는 삭제됩니다. 여기서 삭제 동작이 해당 cell에 대해 개발자가 UIAccessibilityCustomAction를 통해 지정한 custom action 이 됩니다.

이제 UIAccessibilityCustomAction 에 대한 감이 오시나요? 공식 문서에서는 아래와 같이 설명하고 있습니다.

A custom action to perform on an accessible object.

더 자세한 정보는 WWDC 2019 Making Apps More Accessible With Custom Actions 영상에서도 나와있는데요, 해당 영상에서는 UIAccessibilityCustomAction 을 통해 cluster를 줄임으로써, 복잡한 interaction에 대한 편의성과 속도를 증가시킬 수 있다고 합니다.

아래의 Nutter Buddy 앱을 봅시다.

각 cell의 accessibility Element는 ‘셀 자체, 좋아요, 별점 올리기, 별점 내리기’ 4가지로 구성되어 있기 때문에, voice over 사용자는 앱을 아래와 같이 인식할 것입니다.

위에서 잠깐 언급했듯 voice over context에서 좌/우 스와이프다음 accessibility element로 가기 위한 동작입니다. 위와 같은 UI에서 다음 cell로 이동하기 위해서는 스와이프를 꽤 많이 해야할 뿐만 아니라, 특정 동작이 어디 cell 에 속한 것인지도 기억해야합니다.

따라서 영상에서는 좋아요, 별점 올리기, 별점 내리기 동작을 각 cell의 UIAccessibilityCustomAction 으로 설정 함으로써 문제를 해결합니다. 이렇게 하면 유저는 좌우 스와이프마다 바로 이전/다음 cell로 넘어갈 수 있고, 해당 cell에서 좋아요 등의 동작을 하고 싶으면 스와이프 업/다운을 통해 동작을 수행할 수 있습니다.

VoiceOver에서 customAction 이름을 읽지 않는다구요??

cell에 대한 accessibilityCustomAction은 이런 식으로 구현할 수 있습니다.

오키! 좋아! 하고 돌려본 결과는??!

🤔: ??? 왜 name으로 설정된 “customAction”을 안읽어주지..???

그렇습니다. Custom action에 대한 이름을 voice over에서 읽지 않는 상황이 발생한 것이죠.

🤔: 흠.. custom action 자체가 설정이 안된건가..???

라는 생각을 하고 자막을 켜봤습니다. 참고로 자막은 설정 > 손쉬운 사용 > VoiceOver > 자막 패널 에서 설정할 수 있답니다. 아니면 설정 들어가셔서 “자막 패널” 바로 검색하셔도 나와요

좋아요, 그럼 확인해볼까요???

🤔: ??? cell에서 “동작을 사용할 수 있습니다” 도 읽어주고, 여기서 스와이프 했을때 “customAction” 자막도 뜨는데 왜 소리는 안나지;;

대충 “voice over does not read custom action” 정도로 열심히 구글링을 해도 안나와서 당황하고 있던 중에, 제가 설정해야할 문구는 한글이니까 우선 name을 한글로 바꿔봤어요

let customAction = UIAccessibilityCustomAction(
name: "커스텀 액션",
target: self,
selector: #selector(customAction(_:))
)

그리고 돌렸더니?!!!

아니.. 지금.. 하다.. 나랑.. 장난..? 왜 이건 읽어주는건데…????????????????

🤔: 그럼 기본 언어 설정에 영향을 받는건가????

그래서 기본 언어 설정을 영어로 바꾸고,

설정 > 일반 > 언어 및 지역 > iPhone 언어

영어, 한글로 각각 name 이 설정된 custom action을 설정 후에 돌려봤습니다.

let englishCustomAction = UIAccessibilityCustomAction(
name: "CustomAction",
target: self,
selector: #selector(customAction(_:))
)

let koreanCustomAction = UIAccessibilityCustomAction(
name: "커스텀 액션",
target: self,
selector: #selector(customAction(_:))
)

return [englishCustomAction, koreanCustomAction]

음…. 영어도 읽고 한글도 잘 읽어주네요..??? 뭐세요 기본 언어 한글인 사람 차별하세여?????????

여기서 나아가 이런 생각이 들었습니다.

🤔: 흠.. 그럼 영어랑 한글이 섞여 있으면.. 한국어 설정에선 읽어주나???

let englishKoreanCustomAction = UIAccessibilityCustomAction(
name: "CustomAction. 안녕?",
target: self,
selector: #selector(customAction(_:))
)

잘 읽네요…….ㅎㅎㅎㅎ.ㅎ…ㅎ.. 혼란하다 혼란해

이렇게 몇개 돌려보다가 본격적으로 중국어도 추가해서 케이스를 정리해봤습니다.

미디엄 표 지원 언제할건데?

(+ 23.01.10 — iOS 16.0 에서 확인했을 때 기본 설정 한글어로 된 상태에서, 영어는 자막조차 뜨지 않았다. 그리고 한자를 한글로 치환해서 읽는 경우가 생김)

미디엄 표 지원 언제 할건데 222.?

여기서 제가 확실히 알 수 있던 점은, 기본 언어 설정에 따라 voice over에서 읽는 문구의 범위가 달라진다는 사실입니다. (일단 iOS 14.1이랑 14.4 에서는 확인을 했는데, 다른 곳에서는 안그럴까요??)

그렇다면 기본 설정이 한국어로 되어있는 voice over 사용자가 영어권 앱을 사용할 때 문제가 되지 않을까? 라는 생각이 들었습니다. custom action이 없다면야 상관 없겠지만, 만약 존재하고 그 name이 영어로 설정되어 있다면 음성이 나오지 않는 상황이 발생한다고 생각했기 때문입니다.

그래서 확인해보고자 clockology라는 앱으로 테스트를 해봤고, 역시나 Delete 액션에 대해 voice over를 읽어주지 않았습니다.

결론

우선 저는 한국어 사용자 타겟에게 한국어 voice over를 적용하는 상황이기 때문에 결론적으로 큰 이슈는 없었습니다.

하지만 위의 과정들을 거치며 여러 나라에 서비스하는 앱일 수록, 접근성과 로컬라이징에 더더욱 신경 써야겠다는걸 느꼈습니다.

만약 잘못된 부분이 있다면 댓글 부탁드립니다!

오늘도 긴 글 읽어주셔서 감사합니다 :)

참고

--

--