먼저 이미지를 클릭하면 설정한 pictures
중 무작위로 선택된 이미지가 화면에 나타나는 코드가 있다.
// ...
@State private var currentPicture = Int.random(in: 0..<4)
var body: some View {
Image(pictures[currentPicture])
.resizable()
.scaledToFit()
.onTapGesture {
currentPicture = Int.random(in: 0..<4)
}
.accessibilityLabel(labels[currentPicture])
.accessibilityAddTraits(.isButton)
.accessibilityRemoveTraits(.isImage)
}
}
여기서 VoiceOver를 위해 각 이미지마다 설명을 문자열 배열인 labels
의 해당 인덱스로 accessibilityLabel에 전달한다. 그리고 해당 view는 Image이지만 onTapGesture로 버튼의 역할을 부여했기에 .accessibilityAddTraits로 해당 사항을 설정할 수 있다.
Image(pictures[currentPicture])
.resizable()
.scaledToFit()
.onTapGesture {
currentPicture = Int.random(in: 0..<4)
}
.accessibilityLabel(labels[currentPicture])
.accessibilityAddTraits(.isButton)
.accessibilityRemoveTraits(.isImage)
위 코드처럼 Traits를 설정하기 보단 더 간단하게 버튼의 label로 Image를 설정해서 구현할 수 있다.
var body: some View {
Button(action: {
currentPicture = Int.random(in: 0..<4)
}, label: {
Image(pictures[currentPicture])
.resizable()
.scaledToFit()
})
.accessibilityLabel(labels[currentPicture])
.accessibilityAddTraits(.isButton)
.accessibilityRemoveTraits(.isImage)
}
가끔 이미지가 더 나은 UI를 위한 시각 자료(bullet point, 로고의 애니메이션)일 때가 있다. 이때는 accessibility를 위해 VoiceOver에서 감추는 것이 좋다.
Image(decorative: "ales-krivec-15949")
혹은,
Image("ales-krivec-15949")
.accessibilityHidden(true)
그리고 텍스트가 Stack 안에 함께 있어도 끊겨져서 읽히는데, 한 문장으로 읽히도록 설정할 수 있다.
VStack {
Text("Hello this is")
Text("A TEXT")
.font(.title)
}
.accessibilityElement(children: .combine)
accessibilityElement의 기본 값은 .ignore로, 아래처럼 설정해도 된다.
VStack {
Text("Hello this is")
Text("A TEXT")
.font(.title)
}
.accessibilityElement()
.accessibilityLabel("Hello this is a text")
💡 .accessibilityElement는 view들을 숨기는 것이 아니라 상위 view 하나로 읽히도록 설정한다.
.accessibilityValue()로 해당 값을 label로부터 분리할 수 있다. 그리고 .accessibilityAdjustableAction()로 swipe 동작을 설정할 수 있다.
예시로 Increment 버튼을 누르면 value
의 값이 1 증가하고 Decrement 버튼을 누르면 1 감소하는 기능이 있다.
VStack {
Text("value: \(value)")
Button("Increment") {
value += 1
}
Button("Decrement") {
value -= 1
}
}
.accessibilityElement()
.accessibilityLabel("Value")
.accessibilityValue(String(value))
.accessibilityAdjustableAction { direction in
switch direction {
case .increment:
value += 1
case .decrement:
value -= 1
default:
print("not handled")
}
}
value
값을 읽게 한다.💡 default로 모르는 때를 대비하는 것이 좋다.
VoiceOver 작동 영상
https://github.com/treesofgroo/SwiftUI-with-HWS/commit/727c592095719f5b5c8bfd283e9b087e7f61f62c