ios: how to detect if voice dictation was used for UITextField? Or microphone button was tapped on keyboard

拜拜、爱过 提交于 2019-12-07 15:46:11

问题


How to detect if voice dictation was used for UITextField? Or microphone button was tapped on keyboard. Is there any way to do that?


回答1:


UITextField conforms to UITextInput Protocol ( under the section Using Dictation are methods of interest). In this protocol is a method dictationRecordingDidEnd that you can override.

One way is to subclass UITextField and implement the above mentioned method and any others of interest from the UITextInput protocol.

example subclass .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

Unfortunately there is no documented way to detect the actual tap of the microphone button ( dictation did start ).




回答2:


A textfield will report changes when the text input changes including when dictation starts and stops. We can listen for this notification and report when dictation starts and stops.

Here is a Swift subclass using this technique.

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
    }
}

As this class listens for a notification, the notification will be called many times if there is many DictationAwareTextFields. If this is a problem you must move the notification observing code out of the textField into a higher class like the view controller.



来源:https://stackoverflow.com/questions/32652775/ios-how-to-detect-if-voice-dictation-was-used-for-uitextfield-or-microphone-bu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!