【问题标题】:How can I programmatically dismiss the autocorrect popover in a UITextView?如何以编程方式关闭 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
  • 是的。该字段应具有自动更正功能。

标签: ios cocoa-touch uitextview uitextinput


【解决方案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 方法中有一些逻辑时,您为什么要这样做而不是仅仅辞职/成为第一响应者的一个例子是,当您解雇自动更正。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-24
        • 2014-05-29
        • 2012-10-09
        • 2017-10-14
        • 1970-01-01
        • 2013-01-24
        • 2012-08-01
        • 1970-01-01
        相关资源
        最近更新 更多