MBProgressHUD:开启VoiceOver时如何将焦点移至活动指示器?
解决MBProgressHUD在VoiceOver下焦点不锁定的问题
要让VoiceOver焦点持续停留在活动指示器上直到它完成,你需要从无障碍属性配置、主动触发焦点切换和阻止背景元素被访问这三个方面入手,以下是具体步骤和代码示例:
1. 配置MBProgressHUD的无障碍属性
首先要确保HUD本身是VoiceOver可识别的元素,并且有清晰的语义:
- 设置
accessibilityLabel:告诉VoiceOver这个元素的用途,比如"加载中,请稍候" - 设置
accessibilityTraits:标记为UIAccessibilityTraitUpdatesFrequently(适配活动指示器的动态状态),同时加上UIAccessibilityTraitBusy明确它处于忙碌状态 - 开启
isAccessibilityElement:确保HUD被视为一个独立的无障碍元素
2. 将HUD设置为模态无障碍视图
设置HUD所在window的accessibilityViewIsModal为true,这样VoiceOver会直接忽略背景中的所有元素,直到HUD消失,从根源避免焦点跑到背景上。
3. 显示HUD后主动触发VoiceOver焦点切换
通过UIAccessibility.post发送screenChanged通知,让VoiceOver自动聚焦到HUD上,不用用户手动切换。
Swift 代码示例
// 创建并配置HUD let hud = MBProgressHUD.showAdded(to: view, animated: true) hud.mode = .indeterminate hud.label.text = "加载中" // 配置无障碍属性 hud.isAccessibilityElement = true hud.accessibilityLabel = "加载中,请稍候" hud.accessibilityTraits = [.updatesFrequently, .busy] // 设置模态无障碍视图 if let hudWindow = hud.window { hudWindow.accessibilityViewIsModal = true } // 触发VoiceOver焦点切换 UIAccessibility.post(notification: .screenChanged, argument: hud) // 模拟后端调用完成后隐藏HUD DispatchQueue.main.asyncAfter(deadline: .now() + 3) { hud.hide(animated: true) // 隐藏后恢复背景的可访问性 if let hudWindow = hud.window { hudWindow.accessibilityViewIsModal = false } }
Objective-C 代码示例
// 创建并配置HUD MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; hud.mode = MBProgressHUDModeIndeterminate; hud.label.text = @"加载中"; // 配置无障碍属性 hud.isAccessibilityElement = YES; hud.accessibilityLabel = @"加载中,请稍候"; hud.accessibilityTraits = UIAccessibilityTraitUpdatesFrequently | UIAccessibilityTraitBusy; // 设置模态无障碍视图 if (hud.window) { hud.window.accessibilityViewIsModal = YES; } // 触发VoiceOver焦点切换 UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, hud); // 模拟后端调用完成后隐藏HUD dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [hud hideAnimated:YES]; // 隐藏后恢复背景的可访问性 if (hud.window) { hud.window.accessibilityViewIsModal = NO; } });
额外注意事项
- 如果你用了MBProgressHUD的自定义视图,要确保自定义子视图的无障碍属性也配置正确,避免焦点意外落到子元素上
- 隐藏HUD时一定要把
accessibilityViewIsModal设回false,这样背景元素才能重新被VoiceOver访问到
内容的提问来源于stack exchange,提问作者Mugunth Chandran
相关产品推荐
相关产品推荐

