Search code examples
iosuitableviewupdating

iOS Update TableViewCell Contents and REload


On didSelectRowAtIndexPath I want to update the tableviewcell and reload it. I am able to reload but not the content is not getting updated. This is the code that I call from didSelectRowAtIndexPath method. self.visitorlistsTv is my tableview

-(void) showDetails:(NSIndexPath *)indexPath {

if (! [expandedArray containsObject:indexPath]) {
    [expandedArray addObject:indexPath];

    // UPDATE THE IMAGE OF THE BUTTON
    VisitorsListsCell *vcell = (VisitorsListsCell *) [self.visitorlistsTv cellForRowAtIndexPath:indexPath];
    vcell.button.imageView.image = [UIImage imageNamed:@"arrowdown.png"];
    // RELOAD
    [self.visitorlistsTv beginUpdates];
    [self.visitorlistsTv reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath ] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.visitorlistsTv endUpdates];        

} else {
    [expandedArray removeObject:indexPath];

    // UPDATE THE BUTTOM IMAGE
    VisitorsListsCell *vcell = (VisitorsListsCell *) [self.visitorlistsTv cellForRowAtIndexPath:indexPath];
    vcell.button.imageView.image = [UIImage imageNamed:@"arrowup.png"];

    // RELOAD THE DATA
    [self.visitorlistsTv beginUpdates];
    [self.visitorlistsTv reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath ] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.visitorlistsTv endUpdates];
}

}


Solution

  • The simple answer is that your technique for changing a UIButton's image is flawed. Instead use:

    [vcell.button setImage:[UIImage imageNamed:@"arrowdown.png"] forState:UIControlStateNormal];
    

    But beyond that, the way to go about this is to update your model upon selection, call reload for that row and let your cellForRowAt... datasource do the work. That way, that row will look right even after the cell gets disposed of and reused.

    In other words, where you do this:

    vcell.button.imageView.image = [UIImage imageNamed:@"arrowdown.png"];
    

    ... instead, add some state to your model (a string name of the image, or a BOOL that means up vs. down) and set that instead:

    MyModelObject *modelObject = self.model[indexPath.row];
    modelObject.arrowImageName = @"arrowdown.png"; // or the up arrow, depending on the condition
    
    // now do your reload code
    

    Your cellForRowAt... can now lookup the model and update the dequeued cell with:

    MyModelObject *modelObject = self.model[indexPath.row];
    UIImage *image = [UIImage imageNamed:modelObject.arrowImageName];
    [cell.button setImage:image forState:UIControlStateNormal];
    

    One note: your reload code is the same on both branches, so it can be factored out after the conditional.