在 SwiftUI 中實(shí)現(xiàn)音頻圖表
前言
在可訪問性方面,圖表是復(fù)雜的事物之一。iOS 15 引入了一項(xiàng)名為“音頻圖表”的新功能。
下面我們將學(xué)習(xí)如何通過使用 accessibilityChartDescriptor 視圖修飾符為任何 SwiftUI 視圖構(gòu)建音頻表示,呈現(xiàn)類似自定義條形圖視圖或圖像的圖表。
DataPoint 結(jié)構(gòu)體
讓我們從在 SwiftUI 中構(gòu)建一個(gè)簡(jiǎn)單的條形圖視圖開始,該視圖使用垂直條形顯示一組數(shù)據(jù)點(diǎn)。
struct DataPoint: Identifiable {
let id = UUID()
let label: String
let value: Double
let color: Color
}
在這里,我們有一個(gè) DataPoint 結(jié)構(gòu),用于描述條形圖視圖中的條形。它具有 id、標(biāo)簽、數(shù)值和填充顏色。
BarChartView 結(jié)構(gòu)體
接下來,我們可以定義一個(gè)條形圖視圖,它接受一組 DataPoint 結(jié)構(gòu)體實(shí)例并將它們顯示出來。
struct BarChartView: View {
let dataPoints: [DataPoint]
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)
}
}
}
}
}
如上例所示,我們有一個(gè) BarChartView,它接收一組 DataPoint 實(shí)例并將它們顯示為水平堆棧中不同高度的圓角矩形。
ContentView 結(jié)構(gòu)體
我們能夠在 SwiftUI 中輕松構(gòu)建條形圖視圖。接下來讓我們嘗試使用帶有示例數(shù)據(jù)的新 BarChartView。
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")
}
}
在這里,我們創(chuàng)建了一組 DataPoint 實(shí)例的示例數(shù)組,并將其傳遞給 BarChartView。我們還為圖表創(chuàng)建了一個(gè)可訪問元素,并禁用了其子元素的可訪問性信息。為了改進(jìn)圖表視圖的可訪問性體驗(yàn),我們還添加了可訪問性標(biāo)簽。
最后,我們可以開始為我們的條形圖視圖實(shí)現(xiàn)音頻圖表功能。音頻圖表可以通過旋鈕菜單獲得。要使用旋鈕,請(qǐng)?jiān)?iOS 設(shè)備的屏幕上旋轉(zhuǎn)兩個(gè)手指,就像您在撥盤。VoiceOver 會(huì)說出第一個(gè)旋鈕選項(xiàng)。繼續(xù)旋轉(zhuǎn)手指以聽到更多選項(xiàng)。松開手指選擇音頻圖表。然后在屏幕上上下滑動(dòng)手指以導(dǎo)航。
音頻圖表允許用戶使用音頻組件理解和解釋圖表數(shù)據(jù)。VoiceOver 在移動(dòng)到圖表視圖中的條形時(shí)播放具有不同音調(diào)的聲音。VoiceOver 對(duì)于更大的值使用高音調(diào),對(duì)于較小的值使用低音調(diào)。這些音調(diào)代表數(shù)組中的數(shù)據(jù)。
實(shí)現(xiàn)協(xié)議
現(xiàn)在,我們可以討論在 BarChartView 中實(shí)現(xiàn)此功能的方法。首先,我們必須創(chuàng)建一個(gè)符合 AXChartDescriptorRepresentable 協(xié)議的類型。AXChartDescriptorRepresentable 協(xié)議只有一個(gè)要求,即創(chuàng)建 AXChartDescriptor 類型的實(shí)例。AXChartDescriptor 類型的實(shí)例表示我們圖表中的數(shù)據(jù),以 VoiceOver 可以理解和交互的格式呈現(xiàn)。
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 協(xié)議,并添加 makeChartDescriptor 函數(shù),該函數(shù)返回 AXChartDescriptor 的實(shí)例。
首先,我們通過使用 AXCategoricalDataAxisDescriptor 和 AXNumericDataAxisDescriptor 類型定義 X 軸和 Y 軸。我們希望在 X 軸上使用字符串標(biāo)簽,這就是為什么我們使用 AXCategoricalDataAxisDescriptor 類型的原因。在線圖的情況下,我們將在兩個(gè)軸上都使用 AXNumericDataAxisDescriptor 類型。
實(shí)現(xiàn)線圖
接下來,我們使用 AXDataSeriesDescriptor 類型定義圖表中的點(diǎn)。有一個(gè) isContinuous 參數(shù),允許我們定義不同的圖表樣式。例如,對(duì)于條形圖,它應(yīng)該是 false,而對(duì)于線圖,它應(yīng)該是 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 協(xié)議的實(shí)例設(shè)置為描述我們圖表的實(shí)例。
示例截圖:
總結(jié)
音頻圖表功能對(duì)于視力受損的用戶來說是一項(xiàng)重大改進(jìn)。音頻圖表功能的好處是,可以將其用于任何您想要的視圖,甚至包括圖像視圖。只需創(chuàng)建 AXChartDescriptor 類型的實(shí)例。