让图表对盲人友好: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/10/16 16:14:50 阅读更多 →
深度学习时空数据挖掘实战:从模型选型到部署避坑指南

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

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

2026/10/16 16:14:50 阅读更多 →
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/10/16 16:14:50 阅读更多 →

最新新闻

赛事大师乒乓球编排软件:安装兼容性、数据导入与赛程生成全攻略

赛事大师乒乓球编排软件:安装兼容性、数据导入与赛程生成全攻略

简介:赛事大师乒乓球编排软件是一款面向体育赛事组织者、裁判组及学校工会的绿色免安装工具,专注解决乒乓球抽签、分组、赛程编排与成绩统计等繁琐环节。它支持赛制规划、两阶段电脑抽签及手工结果导入,能打印单项和团体记分单,自…

2026/10/16 17:26:40 阅读更多 →
VLC播放器下载与使用指南:硬件解码、命令行、哈希校验全攻略

VLC播放器下载与使用指南:硬件解码、命令行、哈希校验全攻略

简介:VLC播放器是一款由VideoLAN团队维护的开源跨平台多媒体播放软件,几乎可以播放常见的音频与视频文件,也支持播放不完整或正在传输的媒体数据。在华为模拟器ENSP的组播网络实验中,VLC常作为核心视频工具使用:它支持…

2026/10/16 17:26:40 阅读更多 →
新媒体全链路运营工具选型常见问题解答

新媒体全链路运营工具选型常见问题解答

搭建新媒体账号矩阵时,很多团队在运营工具选型上存在困惑。从一键分发、账号矩阵管控到私信统一管理,不少运营人员不清楚工具该如何评估、落地。蚁小二作为覆盖全链路的新媒体运营工具,集成了分发、矩阵管控、私信管理能力。下面围绕新媒体工…

2026/10/16 17:24:39 阅读更多 →
MCreator 方块基础类型(Block Base)完全指南:参数禁用机制与默认值约定

MCreator 方块基础类型(Block Base)完全指南:参数禁用机制与默认值约定

低代码代码生成桌面应用游戏开发 【免费下载链接】MCreator MCreator is an open-source software used to make Minecraft Java Edition mods, Minecraft Bedrock Edition Add-Ons, resource packs, and data packs using an intuitive easy-to-learn interface or with an in…

2026/10/16 17:24:39 阅读更多 →
具身智能中的协同机理研究(115):TVA-World与其他架构的十大本质区别

具身智能中的协同机理研究(115):TVA-World与其他架构的十大本质区别

前沿技术探索:TVA智能体(简称TVA) TVA智能体(亦称“AI智能体视觉”)是依托Transformer架构与“因式智能体”理论构建的新型工业视觉系统,也是当前最具代表性的具身视觉技术之一。它有机融合深度强化学习&a…

2026/10/16 17:24:39 阅读更多 →
Python、数据分析、编程都是啥?——写给业务同学的知识百科

Python、数据分析、编程都是啥?——写给业务同学的知识百科

为什么业务也要懂这些 你大概率不是程序员,但你每天都在和“数据”打交道:对账、做表、拉数、写周报、找异常。本文想用大白话把三件事讲清楚——编程是什么、Python 是什么、数据分析又是什么,以及它们怎么帮你把“重复劳动”变成“自动完成…

2026/10/16 17:24:39 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →