Swift用于旁白识别的控件读取修饰符
Swift用于旁白识别的控件读取修饰符

Swift用于旁白识别的控件读取修饰符

控件修改修饰符

Swift中视图中可能存在操纵控件时,阅读操作按钮困难的情况,例如:

struct ContentView: View {
    @State private var value = 10

    var body: some View {
        VStack {
            Text("Value: \(value)")

            Button("Increment") {
                value += 1
            }

            Button("Decrement") {
                value -= 1
            }
        }
    }
}

在使用旁白时,只能单独阅读值或者增加、减少按钮,无法让使用者了解具体的增减值。

因此,可以VStack中使用accessibilityElement()accessibilityLabel(),忽略子视图的无障碍描述,以及设置一个无障碍描述标签。

VStack {
    Text("Value: \(value)")

    Button("Increment") {
        value += 1
    }

    Button("Decrement") {
        value -= 1
    }
}
.accessibilityElement()
.accessibilityLabel("Value")

在旁白模式下,VStack父视图只会阅读”Value”。

然后添加accessibilityValue()用于阅读控件中的动态值描述:

.accessibilityValue(String(value))   

以及设置accessibilityAdjustableAction()用于无障碍模式下的可调节行为:

.accessibilityAdjustableAction { direction in
    switch direction {
    case .increment:
        value += 1
    case .decrement:
        value -= 1
    default:
        print("Not handled.")
    }
}

设置后,可以通过上滑新增value值,下滑减少value值。

最后,代码内容为:

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 10,阅读的值由accessibilityLabel()和accessibilityValue()组成。

.accessibilityLabel("Value")
.accessibilityValue(String(value))

滑动时,阅读控件的值,如:10、11、12。

总结

使用 accessibilityValue() 为控件添加动态值说明,帮助用户理解状态。

使用 accessibilityAdjustableAction() 定义控件的动态交互行为,允许用户通过手势调整值。

知识扩展

accessibilityValue()

accessibilityValue() 是 SwiftUI 中一个无障碍功能,用来为控件添加动态值描述。它通常用于描述控件的当前值,例如滑块、步进器、开关等。

作用

它提供的信息是动态的,帮助无障碍用户理解控件的当前状态。

使用场景

滑块:显示当前滑块的值。

进度条:展示当前的进度百分比。开关:表明开关是“开启”还是“关闭”状态。

struct ContentView: View {
    @State private var sliderValue = 50.0

    var body: some View {
        Slider(value: $sliderValue, in: 0...100)
            .accessibilityValue("\(Int(sliderValue))%")
            .accessibilityLabel("Brightness")
    }
}

屏幕阅读器朗读内容:Brightness, 50%。

这里 accessibilityLabel 是控件的名称,accessibilityValue 描述了当前的值。

accessibilityAdjustableAction()

accessibilityAdjustableAction() 是 SwiftUI 提供的一种无障碍操作,用来定义控件在无障碍模式下的可调节行为。这通常用于支持增减操作的控件,比如滑块、步进器等。

作用

它允许开发者通过自定义逻辑响应无障碍用户的调节动作,例如“上滑增加”或“下滑减少”。

使用场景

滑块:让用户滑动手势调节值。

自定义控件:定义非默认的增加/减少行为。

struct AdjustableView: View {
    @State private var value = 50

    var body: some View {
        Text("Value: \(value)")
            .accessibilityLabel("Adjustable value")
            .accessibilityValue("\(value)")
            .accessibilityAdjustableAction { direction in
                switch direction {
                case .increment:
                    value += 1
                case .decrement:
                    value -= 1
                @unknown default:
                    break
                }
            }
    }
}

屏幕阅读器用户

向上滑:值增加。

向下滑:值减少。

系统会朗读 “Adjustable value, 50″,并根据 increment 或 decrement 的逻辑调整值并朗读更新后的值。

无障碍阅读顺序

Slider(value: $sliderValue, in: 0...100)
    .accessibilityValue("\(Int(sliderValue))%")
    .accessibilityLabel("Brightness")

屏幕阅读器朗读内容:Brightness, 50%。与修饰符排序不符。

这是因为无障碍模式下,屏幕阅读器(如 iOS 的 VoiceOver)会根据以下顺序朗读控件的信息:

1、accessibilityLabel:控件的名称或描述,告诉用户控件的用途。

2、accessibilityValue:控件的动态值,表示当前状态。

3、其他信息(如果有,如 accessibilityHint 或可调节特性等)。

因此,朗读的顺序是有意设计的,旨在为用户提供清晰的上下文:

1、控件名称:让用户知道控件的功能或作用(这里是 “Brightness”)。

2、控件的状态或值:告诉用户控件当前的状态(这里是 “50%”)。

3、可选提示信息:如果有,通过 accessibilityHint 提供进一步说明。

如何修改顺序?

通常,顺序不应该修改,因为这是标准设计,符合无障碍用户的认知习惯。但如果确实需要,可以将完整的描述放在 accessibilityLabel 中,而忽略 accessibilityValue:

Slider(value: $sliderValue, in: 0...100)
	.accessibilityLabel("Brightness is \(Int(sliderValue))%")

这种情况下,VoiceOver 会直接朗读 “Brightness is 50%”,而不会单独分开名称和值。但请注意,这会使动态值的语义性降低,因此只在特定需求下使用。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注