如何在 MacOS 上实现 VoiceOver 可访问的 NSSlider?
How to Implement NSSlider Accessible for VoiceOver on MacOS?
我有 slider:NSSlider 和 valueLabel:NSTextField,我想知道让 VoiceOver 用户可以访问它的正确方法是什么。
首先,我将滑块的发送操作连接到 sliderChanged 函数以更新 valueLabel。
valueLabel.stringValue = String(slider.integerValue)
VoiceOver 正确读取标签,但它读取滑块的百分比。为了解决这个问题,我将 sliderChanged 函数更改为 setAccessibilityValueDescription。
slider.setAccessibilityValueDescription(String(slider.integerValue))
现在 VoiceOver 可以正确读取滑块的值。但是,它同时看到 valueLabel 和 slider,所以它是多余的。
我试过valueLabel.setAccessibilityElement(false),但 VoiceOver 似乎没有忽略。
有人可以建议实现这个的正确方法是什么吗?谢谢!
最好的方法是创建一个包含标签和滑块的自定义 "ContainerView" class(继承自 UIView),使 ContainerView 成为 accessibilityElement,并设置其 accessibilityTraits "adjustable." 通过创建一个包含 valueLabel 和滑块的 ContainerView,您可以删除当前实现中存在的冗余,同时不会影响非 VoiceOver 的 slider/valueLabel 的布局或可用性用户。此答案基于 this video,因此如果有任何不清楚的地方或您想了解更深入的信息,请观看视频!
将视图的 UIAccessibilityTraits 设置为 "Adjustable" 允许您使用其功能 accessibilityIncrement 和 accessibilityDecrement,以便您可以更新任何您需要的内容(滑块、文本字段等)。此特性允许任何视图像典型的可调整视图一样运行(无需添加 UIGestureRecognizers 或额外的 VoiceOver 通知)。
为了方便起见,我在下面发布了我的代码,但它很大程度上基于我上面链接的视频。 (我个人是一名 iOS 开发人员,所以我的 Swift 代码是基于 iOS 的)
注意 -- 我必须覆盖 "accessibilityValue" 变量 -- 这是为了让 VoiceOver 在用户向上或向下滑动时宣布滑块的变化。
我的 ContainerView class 包含以下代码:
class ContainerView: UIView {
static let LABEL_TAG = 1
static let SLIDER_TAG = 2
var valueLabel: UILabel {
return self.viewWithTag(ContainerView.LABEL_TAG) as! UILabel
}
var slider: UISlider {
return self.viewWithTag(ContainerView.SLIDER_TAG) as! UISlider
}
override var accessibilityValue: String? {
get { return valueLabel.text }
set {}
}
override var isAccessibilityElement: Bool {
get { return true }
set { }
}
override var accessibilityTraits: UIAccessibilityTraits {
get { return UIAccessibilityTraitAdjustable }
set { }
}
override init(frame: CGRect) {
super.init(frame: frame)
valueUpdated()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
valueUpdated()
}
func valueUpdated() {
valueLabel.text = String(slider.value)
slider.sendActions(for: .valueChanged)
}
override func accessibilityIncrement() {
super.accessibilityIncrement()
slider.setValue(slider.value + 1, animated: true)
valueUpdated()
}
override func accessibilityDecrement() {
super.accessibilityDecrement()
slider.setValue(slider.value - 1, animated: true)
valueUpdated()
}
}
希望对您有所帮助!
我有 slider:NSSlider 和 valueLabel:NSTextField,我想知道让 VoiceOver 用户可以访问它的正确方法是什么。
首先,我将滑块的发送操作连接到 sliderChanged 函数以更新 valueLabel。
valueLabel.stringValue = String(slider.integerValue)
VoiceOver 正确读取标签,但它读取滑块的百分比。为了解决这个问题,我将 sliderChanged 函数更改为 setAccessibilityValueDescription。
slider.setAccessibilityValueDescription(String(slider.integerValue))
现在 VoiceOver 可以正确读取滑块的值。但是,它同时看到 valueLabel 和 slider,所以它是多余的。
我试过valueLabel.setAccessibilityElement(false),但 VoiceOver 似乎没有忽略。
有人可以建议实现这个的正确方法是什么吗?谢谢!
最好的方法是创建一个包含标签和滑块的自定义 "ContainerView" class(继承自 UIView),使 ContainerView 成为 accessibilityElement,并设置其 accessibilityTraits "adjustable." 通过创建一个包含 valueLabel 和滑块的 ContainerView,您可以删除当前实现中存在的冗余,同时不会影响非 VoiceOver 的 slider/valueLabel 的布局或可用性用户。此答案基于 this video,因此如果有任何不清楚的地方或您想了解更深入的信息,请观看视频!
将视图的 UIAccessibilityTraits 设置为 "Adjustable" 允许您使用其功能 accessibilityIncrement 和 accessibilityDecrement,以便您可以更新任何您需要的内容(滑块、文本字段等)。此特性允许任何视图像典型的可调整视图一样运行(无需添加 UIGestureRecognizers 或额外的 VoiceOver 通知)。
为了方便起见,我在下面发布了我的代码,但它很大程度上基于我上面链接的视频。 (我个人是一名 iOS 开发人员,所以我的 Swift 代码是基于 iOS 的)
注意 -- 我必须覆盖 "accessibilityValue" 变量 -- 这是为了让 VoiceOver 在用户向上或向下滑动时宣布滑块的变化。
我的 ContainerView class 包含以下代码:
class ContainerView: UIView {
static let LABEL_TAG = 1
static let SLIDER_TAG = 2
var valueLabel: UILabel {
return self.viewWithTag(ContainerView.LABEL_TAG) as! UILabel
}
var slider: UISlider {
return self.viewWithTag(ContainerView.SLIDER_TAG) as! UISlider
}
override var accessibilityValue: String? {
get { return valueLabel.text }
set {}
}
override var isAccessibilityElement: Bool {
get { return true }
set { }
}
override var accessibilityTraits: UIAccessibilityTraits {
get { return UIAccessibilityTraitAdjustable }
set { }
}
override init(frame: CGRect) {
super.init(frame: frame)
valueUpdated()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
valueUpdated()
}
func valueUpdated() {
valueLabel.text = String(slider.value)
slider.sendActions(for: .valueChanged)
}
override func accessibilityIncrement() {
super.accessibilityIncrement()
slider.setValue(slider.value + 1, animated: true)
valueUpdated()
}
override func accessibilityDecrement() {
super.accessibilityDecrement()
slider.setValue(slider.value - 1, animated: true)
valueUpdated()
}
}
希望对您有所帮助!