ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • iOS - 접근성, Voice over, custom UIAccessibilityElement
    ios 2023. 3. 15. 12:20

    iOS 앱 접근성 관련 작업을 하게 됐다.

    voice over 기능 사용 중에 한하여, element에 포커스와 탭 이벤트 발생 시 별도의 기능을 구현하고자 했다.

     

    View의 accessibilityElements에 accessibilityCustomActions 을 설정해 해결하고자 했지만, 
    아래와 같은 문제를 만났다.
    - custom action의 존재 유무가 voice over로 잘 나타나지 않았다.
    - custom action을 사용하기 위해, 포커스가 해당 element로 이동 후, '한 손가락으로 아래 스와이프' 후 더블탭을 해야했다.

    결국 유저 입장에서 custom action 안내를 받지 못하며, 사용을 위해 추가 동작까지 필요했다. 

     

    하여 UIAccessiblityElement를 상속하는 커스텀 클래스를 만들어, 포커스와 탭 이벤트 관련 메소드를 override 했다.

     

    class SomeAccessibilityElement: UIAccessibilityElement {
    //    weak var delegate: SomeDelegate?
        private let _name: String
        
        init(name: String, accessibilityContainer: Any) {
            self._name = name
            super.init(accessibilityContainer: accessibilityContainer)
            self.isAccessibilityElement = true
            self.accessibilityTraits = [.button]
            self.accessibilityLabel = name
        }
        
        override func accessibilityActivate() -> Bool {
    //        delegate?.didTapped(sender: _name)
            print("선택 시 호출, voice over double tap")
            return true
        }
        
        override func accessibilityElementDidBecomeFocused() {
    //        delegate?.didBecomeFocused(sender: _name)
            print("포커스 될 시 호출")
        }
    }

     

    처리는 ViewController 에서 하기 위해 delegate 를 설정했는데 빙 돌아오는 것 같은 느낌이 들었다.
    delegate를 제거할 방법을 찾게 되길..

     


    스크롤뷰 화면 경우 포커스가 계속 이동해도 스크롤이 이동하지 않는 경우도 있음.

    스크린 리더가 포커스 이동에 따른 화면 스크롤을 하지 않는다.

    self.view 가 아닌 scrollView의 accessibilityElements에 요소들을 넣어줘야 한다.

    scrollView.accessibilityElements = scrollviewAccessibilityElements
    view.accessibilityElements = [ scrollView as Any ]

     

    https://stackoverflow.com/questions/31318950/voiceover-not-scrolling-to-elements-offscreen-in-landscape

     


    CollectionViewCell 접근성 적용의 경우, 
    cell에 접근 가능 설정할 시, cell 하위 ui 요소들이 접근 불가능한 문제 있었음.

    - cell 자체를 접근 활성화 하지 말고, 하위 요소들을 활성화 한다. isAccessibilityElement = true
    이후 cell의 accessibilityElements 에 하위 요소들을 담아 parent child 관계 UI 들을 수평 accessibilityElements로 설정했다.

     

    https://stackoverflow.com/questions/56450485/uicollectionview-accessibility-focus

    https://stackoverflow.com/questions/38849389/voiceover-parent-and-child-views-as-accessibility-elements

     


     

    element에 focus 주기 위한 타입 메서드 익스텐션

    extension UIAccessibility {
        /// object에 voice over 스크린 리더 focus 설정
        static func setFocusTo(_ object: Any?, deadline: DispatchTime = .now() + 0.5) {
            if UIAccessibility.isVoiceOverRunning {
                DispatchQueue.main.asyncAfter(deadline: deadline) {
                    UIAccessibility.post(notification: .layoutChanged, argument: object)
                }
            }
        }
    }

    voice over 문구 출력 위한 익스텐션

    extension UIAccessibility {
        /// voice over 안내 메시지 출력
        static func announcement(_ text: String, deadline: DispatchTime = .now() + 0.1) {
            if UIAccessibility.isVoiceOverRunning {
                DispatchQueue.main.asyncAfter(deadline: deadline) {
                    UIAccessibility.post(notification: .announcement, argument: text)
                }
            }
        }
    }

    댓글

Designed by Tistory.