如何以编程方式关闭 UITextView 中的自动更正弹出框?
Posted
技术标签:
【中文标题】如何以编程方式关闭 UITextView 中的自动更正弹出框?【英文标题】:How can I programmatically dismiss the autocorrect popover in a UITextView? 【发布时间】:2012-08-31 14:50:02 【问题描述】:我正在使用 insertText:
自己做一些自定义的自动完成工作,但如果有一个可见的自动更正建议,视图就会进入一个奇怪的状态。
如果我使用[textView unmarkText]
,它会关闭自动更正弹出窗口——但它会接受自动更正(这很糟糕)。有没有办法以编程方式拒绝自动更正建议?
我目前的“解决方案”有效,但它很粗俗,而且我没有理由认为它会在未来继续有效。有没有更好的方法来做到这一点?
- (void)dismissAutocorrectSuggestionForTextView:(UITextView *)textView
NSRange range = textView.selectedRange;
textView.text = textView.text;
textView.selectedRange = range;
【问题讨论】:
有什么原因不能将textView.autocorrectionType
设置为UITextAutocorrectionTypeNo
。
是的。该字段应具有自动更正功能。
【参考方案1】:
我尝试了与您类似的方法,但是以这种方式设置 textView 的文本会导致 textView 不必要地滚动(我的 textView 包含相当多的文本)。我的解决方案涉及以非动画方式恢复 contentOffset。它并不比你所拥有的更优雅,但至少它可以帮助那些需要处理更长文本的人。
至于以后是否会继续工作,我从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];
【讨论】:
【参考方案2】:我自己也遇到了这个问题。此解决方案效果很好:
[textView.inputDelegate textWillChange:textView];
[textView.inputDelegate textDidChange:textView];
【讨论】:
【参考方案3】:您原来的解决方案很接近。请尝试以下操作:
- (void)dismissAutocorrectSuggestionForTextView:(UITextView *)textView
NSRange rangeCopy = textView.selectedRange;
NSString *textCopy = textView.text.copy;
[textView resignFirstResponder];
[textView becomeFirstResponder];
[textView setText:textCopy];
[textView setSelectedRange:rangeCopy];
连续调用 resign/become first responder 会导致文本视图立即接受待处理的自动更正,但不会真正关闭键盘(尝试一下,您会感到惊讶)。这肯定适用于 iOS 6 和 iOS 7。接受自动更正后,您将文本和选定范围重置为自动更正之前的状态。
【讨论】:
这太棒了!谢谢。完美解决问题【参考方案4】:如果不需要从文本视图中退出第一响应者,并且您可以作为委托附加到文本视图,则可以实现方法
- (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;
当文本视图选择更改时,自动完成会尝试接受当前建议,但文本视图会在进行替换之前咨询此方法。例如,当您在 textViewDidBeginEditing
和/或 textViewDidEndEditing
方法中有一些逻辑时,您为什么要这样做而不是仅仅辞职/成为第一响应者的一个例子是,当您解雇自动更正。
【讨论】:
以上是关于如何以编程方式关闭 UITextView 中的自动更正弹出框?的主要内容,如果未能解决你的问题,请参考以下文章
我将如何(以编程方式)将 UITextView 的高度设置为其在 Swift 中的内容大小?