问题:
我的UITextField
与带有发送功能的UIButton
并列。当用户按下发送按钮时,我正在执行简单的操作:
- (IBAction)sendMessage: (id)sender {
[self.chatService sendMessage: self.messageTextField.text];
self.messageTextField.text = @""; // here I get exception
}
现在,当用户开始从键盘使用听写,然后在听写视图(键盘)上按完成,然后立即按发送按钮时,出现异常“范围或索引超出范围”。
可能的解决方案:
我注意到语音识别服务器正在处理数据时,其他应用程序会禁用此“发送”按钮。这恰好在两个事件之间:用户按下“完成”,结果显示在文本字段中。我希望以同样的方式解决它。
我在可以收到此通知的文档中找不到问题。我已经找到了
UITextInput
协议,但这不是我所需要的。相似的主题:
我尝试了什么:
[UITextInputMode currentInputMode].primaryLanguage
等于@"dictation"
时,禁用发送按钮。报告听写模式结束的通知UITextInputCurrentInputModeDidChangeNotification
在听写服务提交新值之前到达,我仍然能够单击发送按钮以引起异常。当primaryLanguage
损失@“dictation”值时,我可以添加延迟,但是我不喜欢这种方法。此所需的延迟很可能取决于语音识别服务的响应速度。 UIControlEventEditingDidBegin
,UIControlEventEditingChanged
,UIControlEventEditingDidEnd
,UIControlEventEditingDidEndOnExit
)。好处是,看起来UIControlEventEditingChanged
恰好在所需的时间触发:当用户在听写视图上按“完成”时,以及服务提交或结束听写时。所以这是到目前为止我最好的概念。 不好的是,是在其他情况下也会触发该事件,并且没有信息可以区分在哪种情况下触发了此控制事件,因此我不知道应该禁用还是启用该按钮或什么也不做。 最佳答案
我终于找到了最终的解决方案。
它简单而优雅,将通过苹果审查,并且始终有效。只需对UIControlEventEditingChanged
做出反应,并检测替换字符的存在,如下所示:
-(void)viewDidLoad {
[super viewDidLoad];
[self.textField addTarget: self
action: @selector(eventEditingChanged:)
forControlEvents: UIControlEventEditingChanged];
}
-(IBAction)eventEditingChanged:(UITextField *)sender {
NSRange range = [sender.text rangeOfString: @"\uFFFC"];
self.sendButton.enabled = range.location==NSNotFound;
}
旧方法
Finlay我找到了一些解决方案。这是对概念nr 3的改进,其中包含了概念nr 2(基于that answer)的混合。
-(void)viewDidLoad {
[super viewDidLoad];
[self.textField addTarget: self
action: @selector(eventEditingChanged:)
forControlEvents: UIControlEventEditingChanged];
}
-(IBAction)eventEditingChanged:(UITextField *)sender {
NSString *primaryLanguage = [UITextInputMode currentInputMode].primaryLanguage;
if ([primaryLanguage isEqualToString: @"dictation"]) {
self.sendButton.enabled = NO;
} else {
// restore normal text field state
self.sendButton.enabled = self.textField.text.length>0;
}
}
- (IBAction)sendMessage: (id)sender {
[self.chatService sendMessage: self.messageTextField.text];
self.messageTextField.text = @"";
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (self.textField.text.length==0 || !self.sendButton.enabled) {
return NO;
}
[self sendMessage: textField];
return YES;
}
// other UITextFieldDelegate methods ...
现在不会出现问题,因为用户有可能在可能发生时被阻止(恰好在用户按下听写视图上的“完成”按钮以及语音识别服务产生结果时)。
好消息是使用了公共API(只有@“dictation”可能是个问题,但我认为Apple应该接受)。