【问题标题】:ios: how to detect if voice dictation was used for UITextField? Or microphone button was tapped on keyboardios:如何检测语音听写是否用于 UITextField?或者在键盘上点击了麦克风按钮
【发布时间】:2015-12-15 15:32:40
【问题描述】:

如何检测 UITextField 是否使用了语音听写?或者在键盘上点击了麦克风按钮。 有什么办法吗?

【问题讨论】:

    标签: ios iphone uiview keyboard voice-recognition


    【解决方案1】:

    UITextField 符合UITextInput Protocol (在使用听写部分下是感兴趣的方法)。 在这个协议中有一个方法 dictationRecordingDidEnd,您可以覆盖它。

    一种方法是继承 UITextField 并从 UITextInput 协议实现上述方法和任何其他感兴趣的方法。

    示例子类 .h

    #import <UIKit/UIKit.h>
    
    @interface BWDictationTextField : UITextField
    
    @end
    

    .m

    #import "BWDictationTextField.h"
    
    @implementation BWDictationTextField
         - (void)dictationRecordingDidEnd {
              NSLog(@"%s", __PRETTY_FUNCTION__);
         }// done is pressed by user after dictation
    @end
    

    不幸的是,没有记录在案的方法来检测麦克风按钮的实际点击(听写确实开始了)。

    【讨论】:

    • 您能否在UITextField 上添加一个类别来实现这些方法而不是子类化?
    • 不确定这是否是最近添加的,但您可以通过检查:textField.textInputMode?.primaryLanguage == "dictation" 在调用 UITextInputCurrentInputModeDidChange 通知时检测到“听写确实开始”
    【解决方案2】:

    当文本输入发生变化时,包括听写开始和停止时,文本字段将报告变化。我们可以监听这个通知,并在听写开始和停止时进行报告。

    这是一个使用这种技术的 Swift 子类。

    protocol DictationAwareTextFieldDelegate: class {
        func dictationDidEnd(_ textField: DictationAwareTextField)
        func dictationDidFail(_ textField: DictationAwareTextField)
        func dictationDidStart(_ textField: DictationAwareTextField)
    }
    
    class DictationAwareTextField: UITextField {
    
        public weak var dictationDelegate: DictationAwareTextFieldDelegate?
        private var lastInputMode: String?
        private(set) var isDictationRunning: Bool = false
    
        override func dictationRecordingDidEnd() {
            isDictationRunning = false
            dictationDelegate?.dictationDidEnd(self)
        }
    
        override func dictationRecognitionFailed() {
            isDictationRunning = false
            dictationDelegate?.dictationDidEnd(self)
        }
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            commonInit()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            commonInit()
        }
    
        private func commonInit() {
            NotificationCenter.default.addObserver(self, selector: #selector(textInputCurrentInputModeDidChange), name: .UITextInputCurrentInputModeDidChange, object: nil)
        }
    
        deinit {
            NotificationCenter.default.removeObserver(self)
        }
    
        @objc func textInputCurrentInputModeDidChange(notification: Notification) {
            guard let inputMode = textInputMode?.primaryLanguage else {
                return
            }
    
            if inputMode == "dictation" && lastInputMode != inputMode {
                isDictationRunning = true
                dictationDelegate?.dictationDidStart(self)
            }
            lastInputMode = inputMode
        }
    }
    

    当这个类监听一个通知时,如果有很多DictationAwareTextFields,这个通知会被多次调用。如果这是一个问题,您必须将通知观察代码从 textField 移到更高的类中,例如视图控制器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-11
      • 1970-01-01
      • 2011-09-05
      • 1970-01-01
      • 2014-02-24
      • 2018-01-13
      • 2015-12-20
      • 1970-01-01
      相关资源
      最近更新 更多