如何移除iOS VoiceOver中SwiftUI DisclosureGroup标签默认的辅助功能提示文本
我太懂这种头疼的感觉了!之前做项目用DisclosureGroup也碰到过这个问题——系统默认给标签加上的“双击展开/收起”提示,完全不符合自己的使用场景,而且试了各种accessibility修饰符都不管用,简直抓狂。
先给你说结论:SwiftUI的DisclosureGroup本身是把标签和展开按钮封装成了一个默认的辅助功能元素,这个提示是系统硬加上的,直接修改标签的accessibility属性基本都会被容器覆盖,很难直接去掉。
不过有两个方向可以解决你的问题:
方案一:强行覆盖标签的辅助功能描述(不一定全版本生效)
如果实在不想放弃系统的DisclosureGroup,可以试试把标签包装成一个独立的辅助功能元素,手动覆盖它的文本和提示,代码大概是这样:
import SwiftUI struct ContentsView: View{ var body: some View { DisclosureGroup( content: {Text("Content, does not have extra reading")}, label: { Text("Label, can't get rid of extra reading") .accessibilityElement(children: .ignore) .accessibilityLabel("Label, can't get rid of extra reading") .accessibilityHint(nil) } ) } }
不过要注意,这个方法在不同iOS版本上的效果可能不一致,比如有些版本的系统还是会偷偷加上默认提示,稳定性不高。
方案二:自己实现自定义展开组件(更推荐)
其实你的使用场景已经偏离了DisclosureGroup的设计初衷——系统的DisclosureGroup默认是把标签和展开动作绑定在一起的,而你是想让标签负责跳页,单独的按钮负责展开收起,这时候自己写一个轻量的组件反而更灵活,还能完全控制VoiceOver的提示内容。
给你个简单的示例代码:
import SwiftUI struct ContentsView: View{ @State private var isExpanded = false var body: some View { VStack(alignment: .leading, spacing: 8) { // 自定义标签+展开按钮 HStack { Text("Label, no more extra reading!") .onTapGesture { // 这里放你的跳转逻辑 } .accessibilityHint("双击跳转到目标页面") // 可以自定义自己的提示 Spacer() // 单独的展开/收起按钮,系统会自动给它正确的VoiceOver提示 Button(action: { isExpanded.toggle() }) { Image(systemName: isExpanded ? "chevron.down" : "chevron.right") } } // 展开内容 if isExpanded { Text("Content, does not have extra reading") .padding(.leading, 16) } } } }
这个方案的好处是,每个元素的辅助功能都完全在你的控制之下:标签会读你设置的跳转提示,展开按钮会自动根据状态读“双击展开”或“双击收起”,完全符合VoiceOver的规范,也不会有多余的默认提示。
我当时就是试遍了各种方法都搞不定DisclosureGroup的默认提示,最后干脆自己写了个自定义组件,反而省了很多麻烦,还能根据需求调整样式和交互。
备注:内容来源于stack exchange,提问作者Ben Z

