You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SwiftUI中判断VoiceOver等辅助技术是否启用?

在SwiftUI中检测辅助技术(如VoiceOver)是否启用

直接调用UIKit的UIAccessibility API在SwiftUI里完全可行,但如果想要更贴合SwiftUI的响应式风格,推荐以下两种实现方式:

方式一:自定义@Environment变量(推荐)

通过自定义环境键,可以把辅助技术状态转化为SwiftUI环境变量,在视图层级中轻松访问,且状态变化时视图会自动更新。

1. 定义环境键

import SwiftUI
import UIKit

private struct VoiceOverEnabledKey: EnvironmentKey {
    static let defaultValue: Bool = UIAccessibility.isVoiceOverRunning
}

extension EnvironmentValues {
    var isVoiceOverEnabled: Bool {
        get { self[VoiceOverEnabledKey.self] }
        set { self[VoiceOverEnabledKey.self] = newValue }
    }
}

2. 监听状态变化并同步到环境

在App入口或根视图中添加监听,实时更新状态:

@main
struct YourApp: App {
    @State private var isVoiceOverEnabled = UIAccessibility.isVoiceOverRunning
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.isVoiceOverEnabled, isVoiceOverEnabled)
                .onAppear {
                    NotificationCenter.default.addObserver(
                        forName: UIAccessibility.voiceOverStatusDidChangeNotification,
                        object: nil,
                        queue: .main
                    ) { _ in
                        isVoiceOverEnabled = UIAccessibility.isVoiceOverRunning
                    }
                }
        }
    }
}

3. 在视图中使用

struct ContentView: View {
    @Environment(\.isVoiceOverEnabled) private var isVoiceOverEnabled
    
    var body: some View {
        Text(isVoiceOverEnabled ? "VoiceOver已启用" : "VoiceOver未启用")
    }
}

方式二:用ObservableObject管理状态

如果需要在多视图或ViewModel间共享状态,可以用ObservableObject封装:

import SwiftUI
import UIKit

class AccessibilityStatusManager: ObservableObject {
    @Published var isVoiceOverEnabled = UIAccessibility.isVoiceOverRunning
    
    init() {
        NotificationCenter.default.addObserver(
            forName: UIAccessibility.voiceOverStatusDidChangeNotification,
            object: nil,
            queue: .main
        ) { [weak self] _ in
            self?.isVoiceOverEnabled = UIAccessibility.isVoiceOverRunning
        }
    }
}

// 视图中调用示例
struct ContentView: View {
    @StateObject private var accessibilityManager = AccessibilityStatusManager()
    
    var body: some View {
        Text(accessibilityManager.isVoiceOverEnabled ? "VoiceOver已启用" : "VoiceOver未启用")
    }
}

补充说明

  • 针对Switch Control、Zoom等其他辅助技术,可复用类似逻辑:监听对应通知(如UIAccessibility.switchControlStatusDidChangeNotification),调用UIAccessibility.isSwitchControlRunning等属性获取状态。
  • 直接使用UIKit的UIAccessibility API本身并无问题,上述方案只是将其适配为SwiftUI的响应式风格,让状态变化自动驱动视图更新。

内容的提问来源于stack exchange,提问作者Jacob Jidell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 07:47:06