Disable auto-correct after entering words with the "@" prefix, and then reuse when entering a new word

In mine, text view

I would like autocorrect to be disabled when entering words starting with "@". The reason is that I have a table menu that pops up and suggests usernames. If a username is selected, the current text is replaced with hyperlink

. This function is very similar to Facebook

.

Everything works fine if autocopy is disabled in my text view. However, if I include autocorrect in my text view, it is at times due to the suggested text. Here is my code where I am trying to change the autocorrect property of a text view in the delegate protocol:

- (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;
}

      

For whatever reason, it doesn't work even if the autocorrect property changes correctly. I checked the autocorrect textview property in the debugger and it was definitely changing, but the behavior as I type is not. The auto-ruler is never disabled when needed because the auto-correct menu is still displayed below the current text:

enter image description here

Edit: This worked. The best solution seems to be to change the responder to a different hidden text, set the original text representation to autocorrectType, and then reassign the original text representation as the first responder. It's a little hacky, but it works and doesn't trigger key presses. It is also important to check the currentViews current autocorrectionType property to prevent assignment of redundant responders. Many thanks to Lindsey for her help with the answer.

  • (BOOL) textView: (UITextView *) textView shouldChangeTextInRange: (NSRange) replacementText range: (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; }

+3


source to share


3 answers


I found Engin Kurutepe 's excellent answer on how to toggle auto-correct correctly.

The solution is very simple, but not documented: you can only modify the properties defined in the UITextInputTraits protocol, while the UITextView in question is NOT the first responder.

So, in this case try:



- (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;
}

      

Edit:

And while the solution is undoubtedly a bit "hacked" as you noted in the comments, the reasoning Engine proposed is not and may well be legitimate, although it has not been properly documented. So, if it is actually true that "you can change the properties defined in the protocol UITextInputTraits

while the UITextView

question is NOT the first responder", then you may have to use "hack", similar to how I posted the code; in this case, you can also edit the method that moves the toolbar based on the keyboard notifications received so that your toolbar does not move if the auto-correct is in the middle. Maybe try using bool like "midToggle"and install / disable it before resignFirstResponder

and becomeFirstResponder

inshouldChangeTextInRange

to let the toolbar know that it remains stationary during these moments.

+4


source


It worked. The best solution seems to be to change the responder to a different hidden text, set the original text properties autocorrectType

, and then reassign the original text representation as the first responder. It's a little hacky, but it works and doesn't trigger keystrokes. It is also important to check the currentViews current autocorrectionType property to prevent assignment of redundant responders. Many thanks to Lindsey for her help with the answer.



- (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;
}

      

+3


source


A less dangerous way to solve this problem is to check if the string you are entering is the string you selected. You can set a variable to hold the row you selected in the didSelectRowInIndexPath file. Then, in the textView delegate method, it shouldChangeTextInRange check if replaceText matches the string you selected in the didSelectRowAtIndexPath. If it doesn't match, it returns false.

0


source







All Articles