如何以编程方式关闭UITextView中的自动更正弹出窗口?

时间:2012-08-31 14:50:02

标签: ios cocoa-touch uitextview uitextinput

我正在使用insertText:自行完成一些自定义自动完成工作,但是如果有一个自动更正建议可见,则视图会进入一种奇怪的状态。

如果我使用[textView unmarkText],它会解析自动更正弹出窗口 - 但它接受自动更正(这是错误的)。有没有办法以编程方式拒绝自动更正建议?

我目前的“解决方案”有效,但它很粗糙,而且我没有理由认为它将来会继续发挥作用。有更好的方法吗?

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

4 个答案:

答案 0 :(得分:6)

我尝试了类似于你的东西,但是以这种方式设置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];
        }
    }
}

答案 1 :(得分:3)

我自己刚刚遇到过这个问题。这个解决方案效果很好:

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

答案 2 :(得分:2)

您原来的解决方案已经结束了。请尝试以下方法:

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

呼叫辞职/成为第一响应者背靠背导致文本视图立即接受待处理的自动更正,但实际上没有解除键盘(尝试它会让你感到惊讶)。这肯定适用于iOS 6和iOS 7。接受自动更正后,然后将文本和所选范围重置为自动更正之前的范围。

答案 3 :(得分:0)

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

- (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方法中有一些逻辑,例如,你不想要当您解除自动更正时执行。