问题
I followed Ray Wenderlich's tutorial on text autocompletion here: http://www.raywenderlich.com/336/how-to-auto-complete-with-custom-values
And it works great, but it only allows searching for a string that is contained in the textView. I need it to search for multiple strings in the same view. For example:
Hi @user, how's @steve
Should search for both occurrences of the @. Here is the original code:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
autocompleteTableView.hidden = NO;
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
return YES;
}
And here is mine:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
NSArray* items = [textView.text componentsSeparatedByString:@"@"];
if([items count] > 0 && [[items lastObject] length]){
NSString *substring = [NSString stringWithString:[items lastObject]];
[self searchAutocompleteEntriesWithSubstring:substring];
}
return YES;
}
And everything works, but it seems to be a character behind. So typing "J" would result in nothing, but "Jo" would return results for "J". I'm thinking it has to do with:
[substring stringByReplacingCharactersInRange:range withString:string]
But anything I try crashes with an NSRange out of bounds.
回答1:
First of all, are we talking about a text field or a text view? They are different! Your code refers to both. I will just go with textField since that's in the name of the method.
At the time you receive textField:shouldChangeCharactersInRange:replacementString:, textField.text has not been changed to contain the replacement string. So when the user types “J”, textField.text doesn't contain the J yet.
Ray's method handles this by performing the substitution. When you try to do the substitution, it fails because your substring variable doesn't contain a copy of textField.text. Your substring only contains a part of textField.text. That's why you get an out-of-bounds exception - your range is out of bounds because substring is shorter than textField.text.
So perhaps you should perform the replacement before you split the string. Try this:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *changedText = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSArray* items = [changedText componentsSeparatedByString:@"@"];
if([items count] > 0 && [[items lastObject] length]){
NSString *substring = [NSString stringWithString:[items lastObject]];
[self searchAutocompleteEntriesWithSubstring:substring];
}
return YES;
}
来源:https://stackoverflow.com/questions/9155381/autocompletion-using-uitextview-should-change-text-in-range