Andrey Chernukha
Andrey Chernukha

Reputation: 21808

Incorrect updating content of UITableView

I have TableView which number of rows depends on the number of NSStrings in NSMutableArray friendsNames.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     return friendsNames.count + 1;
}

Also each row displays that NSString at the respective index of friendsNames. Everything seems to be very simple. But when i remove a string from friendsNames and use reloadData method then weird thing happens: UITableView removes LAST row, not the row with the string which was just removed from friendsNames. Could you please explain me what's going on and what should i do to fix it?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  NSString *MyIdentifier = [NSString stringWithFormat:@"MyIdentifier %i", indexPath.row];

MyTableCell *cell = (MyTableCell *)[friendsList dequeueReusableCellWithIdentifier:MyIdentifier];

if (cell == nil) {
    cell = [[[MyTableCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];

    //create columns
    for (int i = 0;i < 6;i++)
        [cell.contentView addSubview:[self createGrid:i :indexPath]];
}
return cell;
}

and here is the method which creates columns.it's being called from cellForRowAtIndexPath and it's pretty ugly

- (UILabel *)createGrid:(int)columnIndex :(NSIndexPath *)indexPath
  {
CGFloat widths    [6] = {35.0,62.0,35.0,35.0,35.0,35.0};//two arrays holding widths of the columns and points where left sides begin
CGFloat leftSides [6] = {0.0,35.0,97.0,132.0,167.0,202.0};

NSArray *titles = [[[NSArray alloc] initWithObjects:@"Status",@"ID",@"Wins",@"Losses",@"Withdrawls",@"Win %", nil] autorelease]; 

UILabel *columnLabel = [[[UILabel alloc] initWithFrame:CGRectMake(leftSides[columnIndex],0.0,widths[columnIndex], friendsList.rowHeight)] autorelease];

if (indexPath.row == 0)
    columnLabel.text = [titles objectAtIndex:columnIndex];

else
{
    switch (columnIndex)
    {
        case 0:
        {
            BOOL isOnline = [[[receivedUsers objectForKey:[friendsNames objectAtIndex:indexPath.row - 1]] objectAtIndex:0] boolValue];
            columnLabel.text = isOnline ?@"On" :@"Off"; 
        }   
            break;
        case 1:
            columnLabel.text = [friendsNames objectAtIndex:indexPath.row - 1];
            break;
        case 2:
            columnLabel.text = [NSString stringWithFormat:@"%i",[[[receivedUsers objectForKey:[friendsNames objectAtIndex:indexPath.row - 1]] objectAtIndex:1] intValue] ];
            break;
        case 3:
            columnLabel.text = [NSString stringWithFormat:@"%i",[[[receivedUsers objectForKey:[friendsNames objectAtIndex:indexPath.row - 1]] objectAtIndex:2] intValue] ];
            break;
        case 4:
            columnLabel.text = [NSString stringWithFormat:@"%i",[[[receivedUsers objectForKey:[friendsNames objectAtIndex:indexPath.row - 1]] objectAtIndex:3] intValue] ];
            break;
        case 5:
            columnLabel.text = [NSString stringWithFormat:@"%f",[[[receivedUsers objectForKey:[friendsNames objectAtIndex:indexPath.row - 1]] objectAtIndex:4] floatValue] ];
            break;
    }
}

columnLabel.layer.borderColor = [[UIColor blackColor] CGColor];
columnLabel.layer.borderWidth = 1.0;
columnLabel.font              = [UIFont systemFontOfSize:8.0];
columnLabel.textAlignment     = UITextAlignmentCenter;
columnLabel.textColor         = [UIColor blackColor];
columnLabel.autoresizingMask  = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;

return columnLabel;
 }

Upvotes: 0

Views: 143

Answers (1)

Mathieu Hausherr
Mathieu Hausherr

Reputation: 3485

It's a reusable cell problem. Just change your code like that:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *myIdentifier = [NSString stringWithFormat:@"MyIdentifier %i", indexPath.row];

    MyTableCell *cell = (MyTableCell *)[friendsList dequeueReusableCellWithIdentifier:myIdentifier];

    if (cell == nil) {
        //Create a new cell
        cell = [[[MyTableCell alloc] initWithFrame:CGRectZero reuseIdentifier:myIdentifier] autorelease];
    }

    //Configure the cell
    //Remove all columns
    for(UIVIew *subview in cell.contentView.subviews) {
        [subview removeFromSuperview];
    }
    //Create columns
    for (int i = 0;i < 6;i++) {
        [cell.contentView addSubview:[self createGrid:i :indexPath]];
    }
    return cell;
}

Upvotes: 2

Related Questions