让图表对盲人友好:TEAChart VoiceOver 无障碍访问实现原理深度解析
【免费下载链接】TEAChartSimple and intuitive iOS chart library. Contribution graph, clock chart, and bar chart.项目地址https://gitcode.com/gh_mirrors/te/TEAChart点击查看免费下载TEAChart 是一款简单直观的 iOS 图表库内置贡献图、时钟图与柱状图三种图表并完整支持VoiceOver 无障碍访问。这篇文章面向零基础读者带你拆解一个用 Core Graphics 绘制的自绘图表是如何被翻译成视障用户能逐格听懂的语音播报的——看懂之后你能把这套思路搬到任何自绘图表上。为什么自绘图表对 VoiceOver 是盲区像UILabel、UIButton这类系统控件天生自带无障碍信息手指滑过去 VoiceOver 就能念出来。但图表不一样。TEAChart 的每种图表都是在一个UIView里用CGContext直接画出来的——扇形、色块、柱条。系统只看到一堆被填充的像素和路径它根本不知道第 12 格代表3 次提交也不知道某段红色扇形代表上午 10 点到 11 点。所以默认情况下视障用户的手指划过整张图表VoiceOver什么都不会念——因为整张视图对它而言就是一坨没有文字的空View。想让它开口就必须主动把数据翻译成人话。TEAChart 的做法就是给图表里的每一个图形单元每一格、每一根柱、每一段扇形都配一个独立的、能被朗读的元素。TEAChart 的 VoiceOver 无障碍能力一览 三种图表都遵循同一套机制只是念的话术不同图表类型源码文件VoiceOver 会念出示例贡献图TEAChart/TEAContributionGraph.m2026年10月6日3 次提交 / ……无提交柱状图TEAChart/TEABarChart.mA 25.00 %时钟图TEAChart/TEAClockChart.m上午10:30 到 上午11:30下面我们把这套机制拆成原理 → 关键技巧 → 具体话术三层来看。原理一用 UIAccessibilityElement 给图形单元配音iOS 提供了一个UIAccessibilityElement。它不是视图不参与界面布局本质是一个虚拟的可朗读单元只干一件事在屏幕某块区域上念一句你指定的话。要让它生效需要设三样东西initWithAccessibilityContainer:—— 把它挂在哪张图表视图下accessibilityFrame—— 它对应屏幕上的哪块区域用屏幕坐标accessibilityLabel—— 它要念的那句人话。以贡献图为例每画完一天就顺手造一个这样的元素UIAccessibilityElement *dayBlock [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self]; dayBlock.accessibilityFrame [self convertRect:backgroundRect toView:nil]; if (contributions 0) { dayBlock.accessibilityLabel [NSString stringWithFormat:% : %ld Contributions, date, contributions]; } [self.accessibleElements addObject:dayBlock];这里的self.accessibleElements是一个私有数组专门用来收集本视图所有的可朗读单元。原理二让图表视图实现无障碍容器协议造好了一个个元素还不够还得让 VoiceOver知道这些元素的存在。这就要让图表视图实现无障碍容器协议UIAccessibilityElementContainer它一共就四个方法逻辑非常简单方法作用TEAChart 的返回isAccessibilityElement视图本身是否要自己念返回NO我是容器不念内容accessibilityElementCount我里面有几个可朗读单元等于数据条数accessibilityElementAtIndex:按下标取某一个单元返回对应的UIAccessibilityElementindexOfAccessibilityElement:反过来查某个单元的下标在数组里定位以柱状图为例见 TEABarChart.m- (BOOL)isAccessibilityElement { return NO; } - (NSInteger)accessibilityElementCount { return self.data.count; } - (id)accessibilityElementAtIndex:(NSInteger)index { return self.accessibleElements[index]; } - (NSInteger)indexOfAccessibilityElement:(id)element { return [self.accessibleElements indexOfObject:element]; }isAccessibilityElement返回NO意思是我这块整体不念但我里面有子元素VoiceOver 就会转而按accessibilityElementCount逐个遍历、逐个朗读。关键技巧在 drawRect: 里边绘制、边注册✨TEAChart 有个很关键的设计无障碍元素不在别处创建而是在drawRect:里、和图形画出来的同一时刻一起生成。为什么要这么做因为图表的几何信息每根柱多高、每格在哪、每段扇形多大都是在drawRect:里才真正算出来的。既然坐标是这时才确定的那么无障碍框accessibilityFrame也就在这里取——画到哪儿就把朗读区放到哪儿。这样保证了看到的和听到的位置天然一致不会因为某处改动而错位。还有一个容易被忽略的细节accessibilityFrame需要的是屏幕坐标而drawRect:里拿到的是视图内部坐标所以要用[self convertRect:... toView:nil]转换过去。时钟图里还藏着一个坑。它要用CGContextGetPathBoundingBox取当前路径的包围盒当无障碍框这一步必须在CGContextFillPath真正填充扇形之前完成——因为路径一旦被填充/描边当前路径就被清空了再取包围盒就取不到正确的扇形范围了。这段顺序见 TEAClockChart.m。三种图表分别怎么念贡献图逐格播报提交量对应 GitHub 风格贡献日历。它对每一天的色块都生成一个元素日期交给NSDateFormatterNSDateFormatterFullStyle按本地化格式念出来有提交2026年10月6日3 次提交无提交2026年10月6日无提交关键实现见 TEAContributionGraph.m注意有 / 无提交会走不同的话术。柱状图念出柱名与占比对应每根柱子一个元素若设置了xLabels就用标签名如 A来称呼这根柱没设置则自动生成Bar 3 of 8这样的名字保证每根柱都有身份数值不念原始数而是念成百分比A 25.00 %当最大值很大时百分比比原始值更友好。见 TEABarChart.m。时钟图念出起止时间区间对应 Pomotodo元素注册见 TEAClockChart.m。无障碍标签怎么写才自然好听️代码里最能体现为盲人友好的其实不是技术结构而是那句要被念出来的accessibilityLabel。TEAChart 的做法有三个小窍门量纲要带单位—— 说3 次提交25.00 %而不是干巴巴的 3 或 0.25空值也要开口—— 没数据就明说无提交而不是沉默长格式交给系统本地化—— 日期、时间都用NSDateFormatter输出自动适配用户语言与地区。念出来的应该是人话而不是变量值或十六进制色号。关键源码位置速查文件与行号要点位置无障碍元素数组柱状图TEABarChart.m逐柱注册无障碍元素TEABarChart.m容器协议四方法柱状图TEABarChart.m逐日注册无障碍元素TEAContributionGraph.m容器协议四方法贡献图TEAContributionGraph.m扇形包围盒 → 无障碍框TEAClockChart.m容器协议四方法时钟图TEAClockChart.mDemo 装配三种图表TEAViewController.m完整属性文档TEAContributionGraph.h可落地的 iOS 图表无障碍实践清单 ✅如果要把 TEAChart 的思路用到你自己的自绘图表面照着这几点做即可自绘视图默认对 VoiceOver 不可见必须主动实现无障碍别指望系统自动读懂像素每个图形单元 一个UIAccessibilityElementframelabel让容器视图实现四个方法且accessibilityElementCount必须与真实元素数一致accessibilityFrame用屏幕坐标convertRect:toView:nil标签写成人话带单位、处理空值、用本地化日期几何在drawRect:里算就在drawRect:里同步生成元素保证视听位置一致。总结TEAChart 用虚拟元素 容器协议 drawRect: 同步三板斧把三种原本对 VoiceOver 完全失明的自绘图表变成了视障用户能逐格、逐柱、逐段朗读的内容。这套模式不复杂却非常通用——无论是图表、看板、时间轴还是自定义列表只要坚持给每个图形单元配一句人话就能让你的 App 对更多用户真正友好。赞分享【免费下载链接】TEAChartSimple and intuitive iOS chart library. Contribution graph, clock chart, and bar chart.项目地址https://gitcode.com/gh_mirrors/te/TEAChart点击查看免费下载相关推荐Threebox 入门指南如何 10 分钟给 Mapbox 地图加上可交互的 3D 对象Threebox 入门指南如何 10 分钟给 Mapbox 地图加上可交互的 3D 对象 想在地图上放一个 3D 模型、让它能被点击、被拖动、还能沿着导航路线前端3D渲染图形学GISMetaTube SDK Go核心架构解析深入理解Go语言元数据管理SDK设计MetaTube SDK Go核心架构解析深入理解Go语言元数据管理SDK设计 MetaTube SDK Go是一个功能强大的元数据管理SDK专为Go语言开CANN/PTO-ISAMegaMoE调度融合算子示例PTO MegaMoE Dispatch Combine Fusion Example 中文文档 https://link.gitcode.com/i/ab算子库人工智能CANN创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

雅可比矩阵与黑塞矩阵:机器学习中的地形测绘与优化导航

雅可比矩阵与黑塞矩阵:机器学习中的地形测绘与优化导航

1. 这三个矩阵不是数学考试的“拦路虎”,而是你调参、画图、做优化时手边最趁手的工具很多人第一次在机器学习课上看到雅可比矩阵和黑塞矩阵,第一反应是:“这又是个要背公式的抽象玩意儿?”——我当年也是。直到某天调试一个图像风…

2026/11/12 23:07:57 阅读更多 →
深度学习时空数据挖掘实战:从模型选型到部署避坑指南

深度学习时空数据挖掘实战:从模型选型到部署避坑指南

深度学习在时空数据挖掘领域已经彻底改变了游戏规则。如果你做过交通流量预测、气象环境监测或者城市人口流动分析,你大概率经历过传统统计模型被复杂时空关联搞得无能为力的时刻。最近我系统梳理了一篇关于这个方向的综述,结合自己实际做过的几个项目&a…

2026/11/11 8:02:53 阅读更多 →
AMD本地大模型Phi-4-mini-instruct_rai_1.8.0_hybrid是什么?一文读懂Ryzen AI混合推理模型完整概览

AMD本地大模型Phi-4-mini-instruct_rai_1.8.0_hybrid是什么?一文读懂Ryzen AI混合推理模型完整概览

【免费下载链接】Phi-4-mini-instruct_rai_1.8.0_hybrid 项目地址: https://ai.gitcode.com/hf_mirrors/amd/Phi-4-mini-instruct_rai_1.8.0_hybrid 点击查看 免费下载 Phi-4-mini-instruct_rai_1.8.0_hybrid 是 AMD 官方发布的本地大语言模型,基于微软…

2026/11/12 13:14:14 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/12 5:00:00 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/12 5:13:20 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/12 5:13:20 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/12 18:22:26 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/12 5:13:20 阅读更多 →

日新闻

周新闻

月新闻