我如何以编程方式closuresUITextView中的自动更正的popup窗口?

我正在用insertText:自己完成一些自定义自动完成的东西,但是如果有一个自动insertText:的build议可见的话,那么视图会进入一个奇怪的状态。

如果我使用[textView unmarkText] ,它将closures自动[textView unmarkText]popup窗口thingy – 但它接受autocorrection(这是不好的)。 有没有一种方法来编程拒绝自动更正的build议?

我目前的“解决scheme”是有效的,但是这个方法很笨拙,我没有理由认为它将来会继续工作。 有一个更好的方法吗?

 - (void)dismissAutocorrectSuggestionForTextView:(UITextView *)textView { NSRange range = textView.selectedRange; textView.text = textView.text; textView.selectedRange = range; } 

我尝试了类似于你的东西,但是通过这种方式设置textView的文本会导致textView不必要的滚动(我的textView包含了很多文本)。 我的解决scheme涉及以非animation方式恢复contentOffset。 它并不比你拥有的更优雅,但至less可以帮助那些需要处理更长文本的人。

至于是否继续在未来工作,我已经尝试过这样的事情,因为iOS 4,并继续通过iOS 6的工作。

 - (void)rejectAutoCorrectSuggestionInTextView:(UITextView *)textView { if ([textView isFirstResponder]) { NSString *original = textView.text; NSRange originalRange = textView.selectedRange; CGPoint originalOffset = textView.contentOffset; // Force any pending autocorrection to be applied [textView resignFirstResponder]; [textView becomeFirstResponder]; NSString *final = textView.text; if (![original isEqualToString:final]) { textView.text = original; textView.selectedRange = originalRange; [textView setContentOffset:originalOffset animated:NO]; } } } 

您的原始解决scheme非常接近 尝试以下操作:

 - (void)dismissAutocorrectSuggestionForTextView:(UITextView *)textView { NSRange rangeCopy = textView.selectedRange; NSString *textCopy = textView.text.copy; [textView resignFirstResponder]; [textView becomeFirstResponder]; [textView setText:textCopy]; [textView setSelectedRange:rangeCopy]; } 

调用resign /成为第一个响应者会使文本视图立即接受未决的自动更正,但不会真正解除键盘(尝试一下,你会感到惊讶)。 这确实适用于iOS 6和iOS 7。 接受自动更正之后,您将文本和选定范围重置为自动更正之前的内容。

我只是自己遇到了这个问题。 此解决scheme运作良好:

 [textView.inputDelegate textWillChange:textView]; [textView.inputDelegate textDidChange:textView]; 

如果从文本视图中退出第一个响应者是不需要的,您可以将其作为委托添加到文本视图中,则可以实现方法

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text 

并在特定情况下return NO 。 例如,您可以尝试以下操作:

 @implementation { BOOL _denyReplacements; } ////////////// - (void)dismissAutocorrectSuggestionForTextView:(UITextView *)textView { NSRange rangeCopy = textView.selectedRange; NSRange fakeRange = rangeCopy; fakeRange.location--; _denyReplacements = YES; [textView unmarkText]; [textView setSelectedRange:fakeRange]; [textView setSelectedRange:rangeCopy]; _denyReplacements = NO; } - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { return !_denyReplacements; } 

当文本视图select发生变化时,自动完成尝试接受当前的build议,但文本视图在进行replace之前会咨询此方法。 例如,为什么你会这样做,而不是只是辞职/成为第一响应者,就是当你在textViewDidBeginEditing和/或textViewDidEndEditing方法中有一些逻辑的时候,例如当你closures自动纠错时你不想执行的。