Autocompletion using UITextView should change text in range

六眼飞鱼酱① 提交于 2019-12-06 15:02:55

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!