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

SwiftUI TextField键盘语言检测问题:切换后状态不更新

解决UITextInputMode切换键盘后语言检测失效的问题

你的代码出现切换键盘后isAr始终为true的问题,核心原因是逻辑判断不完整:

  • 仅当activeInputModes中存在阿拉伯语输入模式时,才会更新isAr的值
  • 切换到非阿拉伯语键盘时,first(where: { $0.primaryLanguage == "ar" })会返回nil,导致isAr没有被重新赋值,一直保留之前的true状态

修正方案

利用UITextInputMode.currentInputModeDidChangeNotification通知的object属性直接获取当前激活的输入模式(官方文档明确说明该通知的object就是当前活跃的UITextInputMode实例),这样能准确判断当前使用的键盘语言,同时覆盖所有切换场景:

class KeyboardHandler: ObservableObject {
    
    @Published var isAr = false
    
    init() {
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillChange(_:)),
            name: UITextInputMode.currentInputModeDidChangeNotification,
            object: nil
        )
        // 初始化时先检测一次当前键盘语言
        checkCurrentKeyboardLanguage()
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    @objc private func keyboardWillChange(_ notification: Notification) {
        if let inputMode = notification.object as? UITextInputMode {
            isAr = inputMode.primaryLanguage == "ar"
        } else {
            // 兼容极端场景:如果通知object取不到, fallback到activeInputModes检测
            checkCurrentKeyboardLanguage()
        }
        print(isAr)
    }
    
    private func checkCurrentKeyboardLanguage() {
        let currentLang = UITextInputMode.activeInputModes.first?.primaryLanguage
        isAr = currentLang == "ar"
    }
}

补充说明

  1. 新增checkCurrentKeyboardLanguage()方法,用于初始化时就检测一次当前键盘语言,避免初始状态不准确
  2. 优先使用通知的object获取当前输入模式,比遍历activeInputModes更高效准确
  3. 保留fallback逻辑,应对极端情况下通知object为空的场景

SwiftUI中的接收代码无需修改:

.onReceive(keyboardHandler.$isAr) { isAr in
    print(isAr)
}

内容的提问来源于stack exchange,提问作者Mc.Lover

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 01:52:33