Two TextFields in a View Controller set as the delegate, causing the app to crash with NSRange, range or index out of bounds

StackOverflow https://stackoverflow.com/questions/20403027

Question

I have a view controller that annoyingly keeps crashing. The textfield has 3 textFields (name, item, title) and everything was working well before I tried to introduce the UITextFieldDelegate method.

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];

    return YES;
}

When I did that and in viewDidLoad, set the nameTextField as the delegate, as well as itemTextField and titleTextField, when I ran the app and typed a few characters into the itemText/titleTextField, it would crash the program with the following error:

Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString replaceCharactersInRange:withString:]: Range or index out of bounds'

If I simply remove the self.itemTextField.delegate = self, it does not crash the app when I type into that field and the same goes with the titleTextField.

To emphasise this point though, the nameTextField set as the delegate continues to work without crashing. However it appears that adding another textField as the delegate also causes the crashes here.

I have the following two methods which aid in me providing a autocomplete table view under the nameTextField so when users type in, they can reference previously typed in names (stored in Core Data, etc).

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
        self.autoCompleteTableView.hidden = NO;
        self.substring = [NSString stringWithString:self.nameTextField.text];
        self.substring = [self.substring stringByReplacingCharactersInRange:range withString:string];
        NSLog(@"Value of entered string = %@", self.substring);
        [self searchAutocompleteEntriesWithSubstring:self.substring];

        return YES;
}

Which calls:

- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring 
{
    self.autocompleteFetchedResultsController = nil;
    [self autocompleteFetchedResultsController];
    NSLog(@"Table = %@", self.autoCompleteTableView);

    [self.autoCompleteTableView reloadData];
}

I know there are a ton of questions and blog posts relating to this error, but I'm not really sure how to solve this.

I noticed the crash when trying to implement the UITextFieldDelegate method mentioned above and I'm seeing that self.titleTextField.delegate = self in the viewDidLoad is enough to crash this. self.nameTextField.delegate = self is set and that one works regardless of the titleTextField and itemTextField.

Any shedding of light on this would be appreciated! Thanks,

Was it helpful?

Solution

The issue is happening in this method below, You have 3 text fields and all of them call this method but you assume this is happened just for self.nameTextField:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
        self.autoCompleteTableView.hidden = NO;
        self.substring = [NSString stringWithString:self.nameTextField.text];
        self.substring = [self.substring stringByReplacingCharactersInRange:range withString:string];
        NSLog(@"Value of entered string = %@", self.substring);
        [self searchAutocompleteEntriesWithSubstring:self.substring];

        return YES;
}

You can fix it in many ways, it depends what is required for you, one of them is compare that edited text field is your self.nameTextField, but I don't know is it whay you want to achieve:

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
        if (self.nameTextField == textField)
        {
            self.autoCompleteTableView.hidden = NO;
            self.substring = [NSString stringWithString:self.nameTextField.text];
            self.substring = [self.substring stringByReplacingCharactersInRange:range withString:string];
            NSLog(@"Value of entered string = %@", self.substring);
            [self searchAutocompleteEntriesWithSubstring:self.substring];
        }
            return YES;
    }

OTHER TIPS

Move your NSLog statement in shouldChangeCharactersInRange: to the very first line of that function and you will get an idea what's happening.

Hint: your delegates get called from different TextFields...

Change self.nameTextField to textField inside - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range.

You should use the textField that called the delegate, not a class member that could be different that the textField being modified by the user

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top