键入带有“@”前缀的单词后禁用自动更正,然后在键入新单词时重新启用

时间:2014-12-04 23:19:38

标签: ios ios8 uitextview uitextviewdelegate autocorrect

在我的text view中,我希望在输入以" @"开头的单词时禁用自动更正。原因是因为我有一个弹出窗口并建议用户名的tableview菜单。如果选择了用户名,则当前文本将替换为hyperlink。此功能与Facebook非常相似。

如果在文本视图中禁用了自动更正,则一切正常。但是,如果我在文本视图上启用自动更正,由于建议的文本,它有时会混乱。这是我的代码,我试图在委托协议中更改文本视图的自动更正属性:

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

    if ([text isEqualToString:@"@"]) { 

        // text starts with "@" so we disable autocorrect

        textView.autocorrectionType = UITextAutocorrectionTypeNo;

    } else if ([text isEqualToString:@" "]) { 

        // empty space so we reenable autocorrect

        textView.autocorrectionType = UITextAutocorrectionTypeYes;
    }

    return YES;
}

无论出于何种原因,即使正确更改了自动更正属性,它也无法正常工作。我在调试器中验证了textview autocorrect属性,它肯定会被更改,但我输入时的行为是不是。自动更正从不会在需要时禁用,因为自动更正菜单仍显示在当前文本下方:

enter image description here

编辑: 搞定了。最佳解决方案似乎是将响应者更改为隐藏的另一个文本视图,将原始文本视图设置为autocorrectType属性,然后将原始文本视图重新分配为第一个响应者。它有点hacky但它​​有效并且不会导致键盘跳跃。检查textViews当前的autocorrectionType属性以防止冗余响应者分配也很重要。非常感谢Lyndsey帮助我找到答案。

  • (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)范围 replacementText:(NSString *)文本 { if([text isEqualToString:@" @"]&&     textView.autocorrectionType!= UITextAutocorrectionTypeNo){

    // text starts with "@" so we disable autocorrect
    [self.hiddenTextView becomeFirstResponder];
    textView.autocorrectionType = UITextAutocorrectionTypeNo;
    [textView becomeFirstResponder];
    

    }否则if([text isEqualToString:@""]&&            textView.autocorrectionType!= UITextAutocorrectionTypeYes){

    // empty space so we reenable autocorrect
    [self.hiddenTextView becomeFirstResponder];
    textView.autocorrectionType = UITextAutocorrectionTypeYes;
    [textView becomeFirstResponder];
    

    }

    返回YES; }

3 个答案:

答案 0 :(得分:4)

我找到了关于如何正确切换自动更正的精彩回答by Engin Kurutepe

  

解决方案非常简单但未记录:您只能更改   在UITextInputTraits协议中定义的属性   有问题的UITextView不是第一个响应者。

所以在这种情况下试试:

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

    if ([text isEqualToString:@"@"]) { 

        // text starts with "@" so we disable autocorrect
        [textView resignFirstResponder];
        textView.autocorrectionType = UITextAutocorrectionTypeNo;
        [textView becomeFirstResponder];

    } else if ([text isEqualToString:@" "]) { 

        // empty space so we reenable autocorrect
        [textView resignFirstResponder];
        textView.autocorrectionType = UITextAutocorrectionTypeYes;
        [textView becomeFirstResponder];
    }

    return YES;
}

编辑:

虽然解决方案无疑是一个" hack"正如你在评论中指出的那样,Engin提供的推理并不是合理的,即使没有正确记录,它也可能是合法的。因此,如果事实上确实如此,那么您只能更改UITextInputTraits协议中定义的属性,而有问题的UITextView不是第一响应者,"那么也许你会被迫使用" hack"类似于我发布的代码;在这种情况下,您还可以根据收到的键盘通知编辑移动工具栏的方法,以便在自动更正为中间切换时工具栏不会移动。也许尝试使用类似于" midToggle"并在resignFirstResponderbecomeFirstRespondershouldChangeTextInRange之前设置/取消设置它,以便工具栏知道在那些时刻保持静止。

答案 1 :(得分:4)

搞定了。最好的解决方案似乎是将响应者更改为隐藏的另一个文本视图,设置原始文本视图autocorrectType属性,然后将原始文本视图重新分配为第一个响应者。它有点hacky但它​​有效并且不会导致键盘跳跃。检查textViews当前的autocorrectionType属性以防止冗余响应者分配也很重要。非常感谢Lyndsey帮助我找到答案。

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range 
replacementText:(NSString *)text 
{
    if ([text isEqualToString:@"@"] && 
        textView.autocorrectionType != UITextAutocorrectionTypeNo) { 

        // text starts with "@" so we disable autocorrect
        [self.hiddenTextView becomeFirstResponder];
        textView.autocorrectionType = UITextAutocorrectionTypeNo;
        [textView becomeFirstResponder];

    } else if ([text isEqualToString:@" "] && 
               textView.autocorrectionType != UITextAutocorrectionTypeYes) { 

        // empty space so we reenable autocorrect
        [self.hiddenTextView becomeFirstResponder];
        textView.autocorrectionType = UITextAutocorrectionTypeYes;
        [textView becomeFirstResponder];
    }

    return YES;
}

答案 2 :(得分:0)

解决此问题的一种不太常见的方法是检查您输入的字符串是否是您选择的字符串。您可以设置一个变量来保存您在didSelectRowInIndexPath中选择的字符串。然后,在textView的委托方法shouldChangeTextInRange中检查replacementText是否与您在didSelectRowAtIndexPath中选择的字符串匹配。如果不匹配则返回false。