ios: 如何检测 UITextField 是否使用了语音听写?或者点击了键盘上的麦克风按钮
ios: how to detect if voice dictation was used for UITextField? Or microphone button was tapped on keyboard
如何检测 UITextField 是否使用了语音听写?或者点击键盘上的麦克风按钮。
有什么办法吗?
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
遗憾的是,没有记录的方法来检测麦克风按钮的实际点击(听写确实开始)。
当文本输入发生变化时,包括听写开始和停止时,文本字段将报告变化。我们可以收听此通知并在听写开始和停止时报告。
这里是一个Swift子class使用这个技术。
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
}
}
由于此 class 监听通知,如果有很多 DictationAwareTextFields,通知将被调用多次。如果这是一个问题,您必须将通知观察代码从 textField 移到更高的 class,例如视图控制器。
如何检测 UITextField 是否使用了语音听写?或者点击键盘上的麦克风按钮。 有什么办法吗?
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
遗憾的是,没有记录的方法来检测麦克风按钮的实际点击(听写确实开始)。
当文本输入发生变化时,包括听写开始和停止时,文本字段将报告变化。我们可以收听此通知并在听写开始和停止时报告。
这里是一个Swift子class使用这个技术。
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
}
}
由于此 class 监听通知,如果有很多 DictationAwareTextFields,通知将被调用多次。如果这是一个问题,您必须将通知观察代码从 textField 移到更高的 class,例如视图控制器。