Swift Charts 无障碍、回退与资源
目录
- 无障碍
- 有意义的标签
- 自定义 Audio Graphs
- 综合示例
- 回退策略
- 版本细分
- WWDC 会话
- 汇总清单
无障碍
Swift Charts 提供内置的无障碍支持。VoiceOver 用户会自动获得三个转子操作:
- 描述图表(Describe Chart)——坐标轴和数据系列的概览
- 音频图形(Audio Graph)——用音高表示数据值的声波化
- 图表详情(Chart Detail)——用于探索单个数据点的交互模式
有意义的标签
务必在.value(_, _)调用中使用清晰、描述性的字符串。这些标签会被 VoiceOver 朗读并用于 Audio Graph。
// 好 —— 描述性标签LineMark(x:.value("Date",entry.date),y:.value("Daily Steps",entry.count))// 坏 —— 通用标签LineMark(x:.value("X",entry.date),y:.value("Y",entry.count))自定义 Audio Graphs
对于高级无障碍支持,让你的图表视图遵循AXChartDescriptorRepresentable并实现makeChartDescriptor()。用.accessibilityChartDescriptor(self)附加它。
structStepsChart:View,AXChartDescriptorRepresentable{letsteps:[DailySteps]varbody:someView{Chart(steps){dayinLineMark(x:.value("Date",day.date),y:.value("Steps",day.count))}.accessibilityChartDescriptor(self)}funcmakeChartDescriptor()->AXChartDescriptor{guardletfirst=steps.first,letlast=steps.lastelse{returnAXChartDescriptor(title:"Daily Step Count",summary:nil,xAxis:AXNumericDataAxisDescriptor(title:"Date",range:0...1,gridlinePositions:[]){"\($0)"},yAxis:AXNumericDataAxisDescriptor(title:"Steps",range:0...1,gridlinePositions:[]){"\($0)"},additionalAxes:[],series:[])}letxAxis=AXDateDataAxisDescriptor(title:"Date",range:first.date...last.date,gridlinePositions:[])letyAxis=AXNumericDataAxisDescriptor(title:"Steps",range:0...Double(steps.map(\.count).max()??0),gridlinePositions:[]){"\(Int($0))steps"}letseries=AXDataSeriesDescriptor(name:"Daily Steps",isContinuous:true,dataPoints:steps.map{.init(x:$0.date,y:Double($0.count))})returnAXChartDescriptor(title:"Daily Step Count",summary:nil,xAxis:xAxis,yAxis:yAxis,additionalAxes:[],series:[series])}}综合示例
一个结合多个 iOS 17+ API 的、带范围选择的可滚动条形图:
@StateprivatevarselectedRange:ClosedRange<Int>?Chart(weeklyRevenue){weekinBarMark(x:.value("Week",week.index),y:.value("Revenue",week.revenue)).foregroundStyle(by:.value("Region",week.region))}.chartScrollableAxes(.horizontal).chartXVisibleDomain(length:8).chartXSelection(range:$selectedRange).chartXAxis{AxisMarks(values:.stride(by:1)){AxisGridLine()AxisValueLabel{Text("W\($0.as(Int.self)??0)")}}}回退策略
用#available门控高级 API,并提供不带被门控功能回退图表。由于.chartXSelection等图表修饰符会改变返回类型,你必须复制整个Chart——你无法有条件地应用修饰符:
版本细分
- iOS 16+:
Chart、自定义坐标轴、比例尺、BarMark、LineMark、AreaMark、PointMark、RectangleMark、RuleMark、ChartProxy、chartOverlay、chartBackground - iOS 17+:
SectorMark、chartXSelection、chartYSelection、chartAngleSelection、chartScrollableAxes、可见域滚动 API、chartGesture - iOS 18+:
AreaPlot、BarPlot、LinePlot、PointPlot、RectanglePlot、RulePlot、SectorPlot、函数绘图 - iOS 26+:
Chart3D、SurfacePlot、Z 轴 mark、3D 相机与姿态 API
WWDC 会话
- Hello Swift Charts(WWDC 2022)——框架介绍
- Swift Charts: Raise the bar(WWDC 2022)——mark、组合、自定义
- Design an effective chart(WWDC 2022)——图表设计原则
- Design app experiences with charts(WWDC 2022)——将图表集成到应用体验中
- Explore pie charts and interactivity in Swift Charts(WWDC 2023)——SectorMark、选择、滚动
- Swift Charts: Vectorized and function plots(WWDC 2024)——LinePlot、AreaPlot、函数绘图
- Bring Swift Charts to the third dimension(WWDC 2025)——Chart3D、SurfacePlot、3D mark
汇总清单
- 使用图表类型的文件中有
import Charts - 部署目标与所用 API 匹配(iOS 16+ 用
Chart,iOS 17+ 用选择和SectorMark,iOS 18+ 用绘图类型,iOS 26+ 用Chart3D) - 图表数据模型使用
Identifiable(或提供了Chart(data, id:)) - 所有图表系列都用正确的 mark 类型表示
- 当默认刻度过密或不清晰时,坐标轴使用
AxisMarks - 当固定范围很重要时,设置了
chartXScale或chartYScale - 图表级修饰符应用于
Chart,而不是单个 mark - 分类系列使用
foregroundStyle(by:)(而不是手动逐 mark 设置颜色) - 单值选择使用
chartXSelection(value:)或chartYSelection(value:) - 范围选择使用
chartXSelection(range:)或chartYSelection(range:) SectorMark选择使用chartAngleSelection(value:)- iOS 17+、iOS 18+ 和 iOS 26+ API 都用
#available保护 .value()标签描述性强,便于 VoiceOver 和 Audio Graph 无障碍