Skip to content

无障碍 ​

辅助技术——如 macOS 上的 VoiceOver、Linux 上的 Orca、Windows 上的 Narrator 或 NVDA——读取窗口的原生 UI,就像读取其他应用一样:控件及其角色、名称、值和状态,文本,以及随着内容变化而获得焦点的元素。它们也会像键盘和指针那样操作这些元素:按下按钮、勾选复选框、移动滑块、编辑文本输入框并移动焦点。

名称 ​

控件会自我描述,元素内的文本就是它的名称,按钮便是如此。没有文本的元素需要 Label,它也可以用于在测试中定位元素:

go
ui.Slider(c, &app.volume, 0, 100).Label("Volume")
ui.TextInput(c, &app.query).Placeholder("Search").Label("Search")
ui.Box(c).Size(24, 24).Draw(drawIcon).Label("Unread messages")

字段用其标签为控件命名。

角色 ​

其他元素按其作用获得角色:可点击且能获得焦点的元素是按钮,滚动容器是滚动区域,带有 Label 或能获得焦点的元素是分组。Role 为一个外观绘制得像某个控件、但并非由该控件构建的元素设置角色;ui.RoleNone 把元素本身从无障碍信息中排除,但保留其子元素:

go
toggle := ui.Box(c).Size(36, 20).Focusable().Role(ui.RoleSwitch).Label("Wi-Fi")

除了 MyGo 各控件自带的角色之外,ui.RoleHeading 表示章节的标题,用 Level 表示级别;ui.RoleMenu、ui.RoleMenuBar、ui.RoleMenuItem、ui.RoleMenuItemCheckBox 和 ui.RoleMenuItemRadio 用于构建在窗口内绘制的菜单,例如你自己的下拉菜单或菜单栏(元素在窗口内绘制的菜单,PopoverMenu 或 PopoverMenuButton,就使用了这些角色):

go
ui.Text(c, "Appearance").Bold().Role(ui.RoleHeading).Level(2)

状态 ​

各种 Base 控件会告诉辅助技术其控件所显示的状态。你自己的控件可以用下面这些方法来告知,就像 Web 上的 ARIA 状态一样:

方法告知的内容
Checked(on), Mixed()复选框、开关、单选按钮、切换按钮或菜单项是否开启,或部分开启
Expanded(open)元素打开的内容是否显示,如弹窗或章节
Value(s)其值,例如打开弹窗的按钮所显示的选项
Range(lo, hi, value), Step(step)滑块、进度条、仪表或步进器的范围和值,以及按键每次移动的幅度
Level(n)标题的级别,或树中某项的深度
ActiveDescendant(e)元素保留焦点时真正被聚焦的选项,例如菜单或列表中方向键所在的那一项
go
all := ui.CheckboxBase(c, &app.all).Label("Select all")
if app.some {
	all.Mixed()
}

date := ui.ButtonBase(c).Role(ui.RolePopUpButton).Label("Due").Value(app.due.Format("Jan 2")).Expanded(app.picking)

描述与错误 ​

Description 提供比名称更多的信息,例如在其之后朗读的帮助文本,正如工具提示所做的那样;Error 把一个值标记为无效,以便连同朗读一条消息;字段会把它下方的文本给到其控件。

文本格式 ​

富文本编辑器在屏幕阅读器朗读时告知其各文本片段(run)的格式:加粗、斜体、下划线、删除线、链接、字体、颜色和标题。VoiceOver 通过 AXAttributedStringForRange 读取它们,Orca 通过 ATK 的 run 属性,Narrator 通过 UI Automation 的 Text 模式——每个文本字段都支持它,可按字符、格式、单词和行读取。屏幕阅读器也能移动文本字段的选区。

列表与表格 ​

列表的行是列表项,表格的行以其内部的文本命名,并且每一行都会报出自己在所有行中的位置,如"第 5 行,共 10000 行"——即使列表只构建可见的行。可选择行的列表会把焦点交给辅助技术所在的被选中行:按 Up 和 Down 移动选择时会被朗读,聚焦某一行也会选中它。屏幕阅读器移动到可见范围之外时,会请求列表滚动到那里,从而构建滚动经过的行。用 Label 为列表或表格命名。

播报 ​

不移动焦点的新消息——如搜索完成或文件已保存——通过 c.Announce(text) 送达屏幕阅读器,它们会在读完当前内容后朗读一次:即 VoiceOver 和 Orca 的播报,以及 Windows 上 Narrator 和 NVDA 朗读的实时区域(live region)。提示条会播报其文本,路由器会在焦点留在页面之外时播报所显示页面的标题。

go
if ui.Button(c, "Search").Clicked() {
	app.results = search(app.query)
	c.Announce(fmt.Sprintf("%d results", len(app.results)))
}

MyGo 只在辅助技术请求后才描述无障碍框架,因此应用在其他情况下无需为此付出任何开销。

每个组件的文档页面都会说明辅助技术能看到什么。