在可访问性方面,图表是复杂的事物之一。iOS 15 引入了一项名为“音频图表”的新功能。下面我们将学习如何通过使用 accessibilityChartDescriptor 视图修饰符为任何 SwiftUI 视图构建音频表示,呈现类似自定义条形图视图或图像的图表。
struct DataPoint: Identifiable { let id = UUID() let label: String let value: Double let color: Color }
在这里,我们有一个 DataPoint 结构,用于描述条形图视图中的条形。它具有 id、标签、数值和填充颜色。
struct BarChartView: View { let dataPoints: [DataPoint] // 堆代码 duidaima.com var body: some View { HStack(alignment: .bottom) { ForEach(dataPoints) { point in VStack { RoundedRectangle(cornerRadius: 8, style: .continuous) .fill(point.color) .frame(height: point.value * 50) Text(point.label) } } } } }
如上例所示,我们有一个 BarChartView,它接收一组 DataPoint 实例并将它们显示为水平堆栈中不同高度的圆角矩形。
struct ContentView: View { @State private var dataPoints = [ DataPoint(label: "1", value: 3, color: .red), DataPoint(label: "2", value: 5, color: .blue), DataPoint(label: "3", value: 2, color: .red), DataPoint(label: "4", value: 4, color: .blue), ] var body: some View { BarChartView(dataPoints: dataPoints) .accessibilityElement() .accessibilityLabel("Chart representing some data") } }
在这里,我们创建了一组 DataPoint 实例的示例数组,并将其传递给 BarChartView。我们还为图表创建了一个可访问元素,并禁用了其子元素的可访问性信息。为了改进图表视图的可访问性体验,我们还添加了可访问性标签。
最后,我们可以开始为我们的条形图视图实现音频图表功能。音频图表可以通过旋钮菜单获得。要使用旋钮,请在 iOS 设备的屏幕上旋转两个手指,就像您在拨盘。VoiceOver 会说出第一个旋钮选项。继续旋转手指以听到更多选项。松开手指选择音频图表。然后在屏幕上上下滑动手指以导航。
音频图表允许用户使用音频组件理解和解释图表数据。VoiceOver 在移动到图表视图中的条形时播放具有不同音调的声音。VoiceOver 对于更大的值使用高音调,对于较小的值使用低音调。这些音调代表数组中的数据。
extension ContentView: AXChartDescriptorRepresentable { func makeChartDescriptor() -> AXChartDescriptor { let xAxis = AXCategoricalDataAxisDescriptor( title: "Labels", categoryOrder: dataPoints.map(\.label) ) let min = dataPoints.map(\.value).min() ?? 0.0 let max = dataPoints.map(\.value).max() ?? 0.0 let yAxis = AXNumericDataAxisDescriptor( title: "Values", range: min...max, gridlinePositions: [] ) { value in "\(value) points" } let series = AXDataSeriesDescriptor( name: "", isContinuous: false, dataPoints: dataPoints.map { .init(x: $0.label, y: $0.value) } ) return AXChartDescriptor( title: "Chart representing some data", summary: nil, xAxis: xAxis, yAxis: yAxis, additionalAxes: [], series: [series] ) } }我们所需做的就是符合 AXChartDescriptorRepresentable 协议,并添加 makeChartDescriptor 函数,该函数返回 AXChartDescriptor 的实例。
实现线图
接下来,我们使用 AXDataSeriesDescriptor 类型定义图表中的点。有一个 isContinuous 参数,允许我们定义不同的图表样式。例如,对于条形图,它应该是 false,而对于线图,它应该是 true。struct ContentView: View { @State private var dataPoints = [ DataPoint(label: "1", value: 3, color: .red), DataPoint(label: "2", value: 5, color: .blue), DataPoint(label: "3", value: 2, color: .red), DataPoint(label: "4", value: 4, color: .blue), ] var body: some View { BarChartView(dataPoints: dataPoints) .accessibilityElement() .accessibilityLabel("Chart representing some data") .accessibilityChartDescriptor(self) } }作为最后一步,我们使用 accessibilityChartDescriptor 视图修饰符将符合 AXChartDescriptorRepresentable 协议的实例设置为描述我们图表的实例。