element119
element119

Reputation: 7625

UITableView Inserting Old Data

I have a simple UITableView with 1 section, within which an arbitrary amount of rows with custom UITableViewCells (of type KMInputCell) with UITextFields exist. When a user starts typing in the last (blank) text field, a new blank row is inserted (so the user can make a list-like structure). Since I will only "save" the data when the view is closed, the data source is just an NSUInteger keeping track of the number of rows.

My code works fine until after a user has deleted a row from the table. Then, when the user starts typing at the end of the list and a new (blank) row should be inserted, the inserted UITableView cell contains old data from the deleted cell. Worse, when multiple rows are deleted and then the user starts typing (and one blank row should be inserted), multiple deleted rows become suddenly present.

Here is the fieldChanged: method that is called when one of the UITextFields in the cells is edited (where self.last_cell returns the last cell in the section):

- (IBAction)fieldChanged:(id)sender {
    // get the text field of the last row
    // if it has a value that is not blank, insert another row
    KMInputCell* last_cell = self.last_cell;
    if(![last_cell.textField.text isEqualToString:@""]){
        [self.tableView beginUpdates];
        NSIndexPath* new_cell_path = [NSIndexPath indexPathForItem:[self.tableView numberOfRowsInSection:0] inSection:0];
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:new_cell_path] withRowAnimation:UITableViewRowAnimationAutomatic];
        number_emails++;
        [self.tableView endUpdates];
    }
}

Here is the commitEditingStyle: method that is used to delete cells:

// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        number_emails--;
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
     }   
}

Addition

Here is cellForRowAtIndexPath::

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"add_email_prototype";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];=

    // Configure the cell...

    return cell;
}

Upvotes: 0

Views: 678

Answers (2)

Prajwal Udupa
Prajwal Udupa

Reputation: 860

In cellForRowIndex function just initialize them back to nil. this will solve the problem.

Upvotes: 0

isaac
isaac

Reputation: 4897

I'm not exactly clear on the particulars of your data model... just keeping track of an integer isn't really a great approach - but perhaps I just don't understand what you've got going on. Do you have a model array or model objects representing these rows, or are you just tracking the text in their fields?

You're inserting new rows, but the issue might pertain to the fact the UITableViewCells are reused when being presented. If that is indeed the problem here, you may need to update a method you haven't provided here:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...

    return cell;
}

This should be the method you are using to populate the text fields. It is necessary as well, to explicitly clear the contents of any dynamic fields such that, when table cells are re-used, you don't get unexpected contents in them.

UPDATED

Text fields themselves aren't suitable for retaining data. The architecture, as you can see from the issue here, precludes it because the cells are re-used as they scroll on and off the screen (or are removed/added). One course of action would be to just create an array and store the contents of these textfields as strings within it.

Upvotes: 1

Related Questions