【发布时间】:2015-12-15 15:32:40
【问题描述】:
【问题讨论】:
标签: ios iphone uiview keyboard voice-recognition
【问题讨论】:
标签: ios iphone uiview keyboard voice-recognition
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 上添加一个类别来实现这些方法而不是子类化?
当文本输入发生变化时,包括听写开始和停止时,文本字段将报告变化。我们可以监听这个通知,并在听写开始和停止时进行报告。
这是一个使用这种技术的 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 移到更高的类中,例如视图控制器。
【讨论】: