0

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

如果我使用[textView unmarkText],它会关闭自动更正弹出窗口——但它接受自动更正(这很糟糕)。有没有办法以编程方式拒绝自动更正建议?

我目前的“解决方案”有效,但它很粗俗,而且我没有理由认为它会在未来继续有效。有一个更好的方法吗?

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

4 回答 4

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];
        }
    }
}
于 2012-10-22T13:10:09.777 回答
3

I just encountered this issue myself. This solution works well:

[textView.inputDelegate textWillChange:textView];
[textView.inputDelegate textDidChange:textView];
于 2015-01-31T18:53:43.680 回答
2

您的原始解决方案很接近。尝试以下操作:

- (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。接受自动更正后,您将文本和选定范围重置为自动更正之前的状态。

于 2013-08-31T22:44:14.177 回答
1

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

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

于 2014-03-30T14:23:46.927 回答