티스토리 뷰

728x90
반응형

 

[1] SwiftUI hyperlink accessibility

 

SwiftUI Text 에 마크다운을 넘기거나  (참고: 예제)

struct ContentView: View {
    
    var body: some View {
        Text("Hello") + Text("[Apple](https://www.apple.com)")
    }
}

 

 

AttributedString  를 넘기면

struct ContentView: View {
    
    var attributed: AttributedString {
        let hello = AttributedString("Hello")
        var apple = AttributedString("Apple")
        apple.link = URL(string: "https://www.apple.com")
        return hello + apple
    }

    var body: some View {
        Text(attributed)
    }
}

 

접근성은 이렇게 된다.  

다음과 같이 읽어주고 더블탭하면 링크로 이동 (테스트환경:  iOS 17.2.1)

 

 

 

 

 

마크다운/AttributedString 안쓰고 링크 스타일을 사용하는 경우 (DeploymentTarget 때문 이라던가..)
똑같이 대응하려면 아래 코드처럼 해준다. 

참고로 accessibilityAddTraits(.isLink) 를 HStack 에 해줘도 상관없다. 

struct ContentView: View {
    
    var body: some View {
        HStack(spacing: 0) {
            Text("Hello")
            Text("Apple")
                .foregroundStyle(.blue)
                ✅.accessibilityAddTraits(.isLink)
                .onTapGesture {
                    print("do something..")
                }
        }
        ✅.accessibilityElement(children: .combine)
    }
}

 

위와 동일하게 읽어주고 더블탭 했을때도 동일하게 동작한다. 

 

 

[2] UIKit hyperlink accessibility 

 

UIKit 에서 label과 textview 에 링크를 넣어쓰는 경우

보이스오버가 어케 읽어줬는 지 재확인해보자 

let attributed = NSMutableAttributedString(string: "Hello, Apple")
attributed.addAttribute(.link, value: "https://www.apple.com", range: (attributed.string as NSString).range(of: "Apple"))

label.attributedText = attributed

textView.attributedText = attributed
textView.isEditable = false

 

 

label 은 이렇게

 

 

 

text view 는 이렇게  (isEditable 가 true 일 경우는 또 다름) 

 

 

 

 

SwiftUI 랑 UIKit 을 같이 쓰는 경우,  보이스오버가 읽어주는 스타일을 맞춰야하는데

텍스트 뷰 스타일로 통일시켜보자!

 

accessibiltiyHint 를 하드코딩해주면 된다.  (현지화땜에 accessibilityHint 디폴트값을 애플이 제공해주면 좋겠는데 ㅠㅠ.. )

var body: some View {
    HStack(spacing: 0) {
        Text("Hello")
        Text("Apple")
            .foregroundStyle(.blue)
            .onTapGesture {
                print("do something..")
            }
    }
    .accessibilityElement(children: .combine)
    .accessibilityHint("내장된 링크를 활성화하려면 이중 탭 하십시오")

 

 

위처럼 간단한 예제에서는 더블탭이 잘먹히나 뷰가 여러개 중첩되어있거나 복잡한 코드에서는 더블탭 안먹힐 때가 있었다. 

그럴땐 이런 extension 을 활용해줄 수 있다. 

 

accessibilityAction 은 더블탭했을 때 불리는데 여기에 tapAction을 전달해주면 된다.

accessibilityAction 는 해당 뷰의 trait 을 button 으로 바꾸는 듯하다.  

그래서 버튼 이라고 읽어주지 않도록 removeTrait 을 같이 해준다. 

extension View {
    func accessibilityContainingLink(onDoubleTap: @escaping () -> Void) -> some View {
        self
            .accessibilityHint("내장된 링크를 활성화하려면 이중 탭 하십시오")
            .accessibilityRemoveTraits(.isButton)
            .accessibilityAction {
                onDoubleTap()
            }
    }
}

 

 

근데 이걸 활용하는 것보다 코드를 리팩토링하는 걸 추천! 웬만한 계층에서는 accessibilityAction 을 안넘겨줘도

접근성 > 더블탭 잘 됨! 

 

 

 

반응형

'🍏 > Accessibility' 카테고리의 다른 글

[SwiftUI] AccessibilityElements like UIKit  (0) 2023.12.26
[iOS] Accessibility 관련 헷갈리는 것 정리  (0) 2021.07.27
[iOS] Custom Rotor  (0) 2021.06.09
[iOS] Accessibility in SwiftUI  (0) 2021.06.06
[iOS] UIAccessibilityCustomAction  (0) 2021.06.01
댓글