In my text view
I would like autocorrect to be disabled when typing words that start with "@". The reason being is because I have a tableview menu that popups and suggests usernames. If a username is selected the current text is replaced with a hyperlink
. This functionality is very similar to Facebook
.
Everything works great if autocorrect is disabled on my text view. However if I enable autocorrect on my text view it messes up at times because of the suggested text. Here is my code where I am attempting to change the text view's autocorrect property 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's not working even though the autocorrect property is correctly being changed. I verified the textview autocorrect property in the debugger and it's definitely being changed but the behavior while I am typing isn't. The auto correct never disables when needed because the autocorrect menu still appears below the current text:
Edit: Got it working. The best solution seems to be to changing your responder to another textview that is hidden, set the original text views autocorrectType property and then reassign the original text view as the first responder. It's a little hacky but it works and doesn't cause the keyboard to jump. Also it's important to check the textViews current autocorrectionType property to prevent redundant responder assignments. Many thanks to Lyndsey for helping me get to 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; }
I found a great answer by Engin Kurutepe about how to properly toggle autocorrect.
The solution is very simple but not documented: You can only change 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 although the solution is undoubtedly a bit of a "hack" as you pointed out in the comments, the reasoning Engin provided isn't and it might very well be legit even though it's not properly documented. So, if it is in fact true that "you can only change the properties defined in the UITextInputTraits
protocol while the UITextView
in question is NOT the first responder," then perhaps you'll be forced to use a "hack" similar to the code I posted; in which case, you can also edit the method that shifts the toolbar based on the received keyboard notifications so that your toolbar doesn't shift if the autocorrect is mid-toggle. Perhaps try using a bool like "midToggle" and set/unset it before resignFirstResponder
and becomeFirstResponder
in shouldChangeTextInRange
so that the toolbar knows to stay stationary in those moments.
Got it working. The best solution seems to be to changing your responder to another textview that is hidden, set the original text views autocorrectType
property and then reassign the original text view as the first responder. It's a little hacky but it works and doesn't cause the keyboard to jump. Also it's important to check the textViews current autocorrectionType property to prevent redundant responder assignments. Many thanks to Lyndsey for helping me get to 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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With