views:

588

answers:

1

Hello,

I've been doing a lot of Googling to try to figure out the correct way of doing this, and so far I am at a loss.

I have subclassed UITableViewCell with my own view and I am trying to animate the height of a UITableViewCell to expand when it is selected, and to contract when it is selected again. This table has the potential to contain thousands of rows, so I don't want to override the tableView's heightForRowAtIndexPath. Ideally I'd like to be able to have more than one cell expanded at a time, but that isn't as critical. What is the best way to do this?

Thank you, Justin

+2  A: 

There is no other mechanism for specifying cell height than heightForRowAtIndexPath. Unless you're properly accounting for the expanded cell in that method you're going to find your other cells either running over it or hidden under it. From boneheaded code where I forgot to set up heightForRowAtIndexPath, I'm pretty sure your other cells will be displayed over it.

Since you're talking thousands of rows, we'll assume the user can't rearrange the cells.

What you could do is store the expanded cell's index path when the user taps a given cell. Then, heightForRowAtIndexPath might look like this:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{

if ([indexPath compare:lastSelectedIndexPath] == NSOrderedSame)
{
 return 80;
}

else {
 return 44;
}

}

If you really want multiple selections, you could store the appropriate index paths to an array and check for them like this:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{

CGFloat cellHeight = 44;

for (NSIndexPath *expandedIndexPath in expandedIndexPathsArray)
{
 if ([indexPath compare:expandedIndexPath] == NSOrderedSame)
 {
  cellHeight = 80;
  break;
 }
}

return cellHeight;

}

Getting the animation to look right will take some work. I've toyed with this particular UI idea for awhile now and could never bring myself to sit down and really make it happen. One thing you could do is display a dummy view that animates while you're updating the tableview behind it.

- (void)reloadRowsAtIndexPaths:(NSArray *)indexPathswithRowAnimation:(UITableViewRowAnimation)animation

could be of interest for this as you might be able to use the cell animations to simulate movement of the cells below to accommodate your expansion.

If you can forgo animating the cell's frame altogether, you could do an opacity animation of the expanded data once the new height has been set.

It's a toughie but if you make it work I bet it'll be pretty cool. Good luck.

Danilo Campos
Thanks Danilo, you got me started on the right path. I ended up getting it working by using reloadRowsAtIndexPaths within didSelectRowAtIndexPath. I check to see if the cell is expanded and set the corresponding height in heightForRowAtIndexPath, just like you mentioned. Thanks again!
Justin
Too cool! Glad to give you a helpful nudge. Hope it works out. Maybe I'll finally give it a try myself one of these days.
Danilo Campos