Search code examples
iosuitableviewautolayoutlayoutsubviews

UITableView: How to change cell height dynamically when a button is clicked in it?


I have a UITableView, in which each cell has a button.
When the button is clicked, the cell's height will be changed.
Of course, the whole tableview height will be changed according to it.
I cannot find a way during long surfing. What is an elegant solution to achieve this?


Solution

  • (See this answer. Kudos to Tapas Pal for writing the original answer. I just changed it to better fit your question.)

    You will need a BOOL variable to tell the cell that its height should be different from the others. You will also need a number (here, I will use NSInteger) variable so that you can increase the height for the right cell.

    BOOL shouldCellBeExpanded = NO;
    NSInteger indexOfExpandedCell = -1;
    

    Then, in your -tableView:cellForRowAtIndexPath: method, add the following to where you design your cell. You will set the button tag to be the same as its cell's row so that you know what cell to expand. Moreover, if you need to add any elements to the cell, you can do it inside the if statement.

    [[cell aButton] setTag:[indexPath row]];
    
    if(shouldCellBeExpanded && [indexPath row] == indexOfExpandedCell)
    {
       // design your read more label here
    }
    

    Moving to the button's IBAction. When the button is tapped, the UITableView will reload the cell that button is on. Note: if you use multiple sections in your UITableView, you will need to add another number variable to account for that. Comment if you need help.

    -(IBAction) aButtonTapped:(id)sender
    {
        UIButton *aButton = (UIButton *)sender;
        indexOfExpandedCell = [aButton tag];
        shouldCellBeExpanded = YES;
    
        [[self tableView] beginUpdates];
        [[self tableView] reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForItem: indexOfExpandedCell inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
        [[self tableView] endUpdates];
    }
    

    Finally, in the -tableView:heightForRowAtIndexPath: method:

    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(shouldCellBeExpanded && [indexPath row] == indexOfExpandedCell)
            return 200.0f; //Your desired height for the expanded cell
        else
            return 100.0f; //The other cells' height
    }
    

    What this does is check if a cell is expected to be expanded and, if so, whether that cell is the one currently being asked for a height value. If it is, then the returned value is the expanded height. If not, the original one.