Reputation: 3545
How to detect if voice dictation was used for UITextField? Or microphone button was tapped on keyboard. Is there any way to do that?
Upvotes: 5
Views: 5416
Reputation: 7332
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.
Upvotes: 3
Reputation: 5680
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 ).
Upvotes: 7