I use UITableView in my iPhone app and have a list of people in a group. I want this so that when a user clicks a specific person (and thus selects a cell), the height of the cell increases to show multiple UI controls for editing that person's properties.
Is that possible?
#1 building
I just solved this problem with a little skill:
static int s_CellHeight = 30; static int s_CellHeightEditing = 60; - (void)onTimer { cellHeight++; [tableView reloadData]; if (cellHeight < s_CellHeightEditing) heightAnimationTimer = [[NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(onTimer) userInfo:nil repeats:NO] retain]; } - (CGFloat)tableView:(UITableView *)_tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (isInEdit) { return cellHeight; } cellHeight = s_CellHeight; return s_CellHeight; }
When I need to increase the pixel height, I set isInEdit = YES and call the method [self onTimer], which will animate the pixel growth until the s_cellhighterediting value is reached: -)
#2 building
Add properties to track selected cells
@property (nonatomic) int currentSelection;
Set it to (for example) the sentry value of viewDidLoad to ensure that UITableView starts at the "normal" position
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. //sentinel self.currentSelection = -1; }
In the highforrowatindexpath, you can set the height required for the selected cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ int rowHeight; if ([indexPath row] == self.currentSelection) { rowHeight = self.newCellHeight; } else rowHeight = 57.0f; return rowHeight; }
In didSelectRowAtIndexPath, save the current selection and save the dynamic height if necessary
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // do things with your cell here // set selection self.currentSelection = indexPath.row; // save height for full text label self.newCellHeight = cell.titleLbl.frame.size.height + cell.descriptionLbl.frame.size.height + 10; // animate [tableView beginUpdates]; [tableView endUpdates]; } }
Set the selection index back to the outpost value in didDeselectRowAtIndexPath and animate the cell
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { // do things with your cell here // sentinel self.currentSelection = -1; // animate [tableView beginUpdates]; [tableView endUpdates]; } }
#3 building
I found a very simple solution, which is a side effect of UITableView that I am studying.
The pixel height is stored in the variable that normally reports the original height through tableview: highforrowatindexpath:, and then when you want to animate the height change, just change the value of the variable and call it.
[tableView beginUpdates]; [tableView endUpdates];
You will find that it will not be completely overloaded, but it is enough for UITableView to know that it must redraw cells to get the new height value of cells.... guess what? Animate changes for you. Sweet.
I have a more detailed explanation and a complete code example on my blog . Animate UITableView cell height change
#4 building
I don't know what all the content of continuous call beginUpdates / endUpdates is, you can just use - [uitableview reloadrowsatindexpaths: with animation:]. This is a sample project .
#5 building
Try this to extend by index row
@property (nonatomic) NSIndexPath *expandIndexPath; - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath { if ([indexPath isEqual:self.expandedIndexPath]) return 100; return 44; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSMutableArray *modifiedRows = [NSMutableArray array]; if ([indexPath isEqual:self.expandIndexPath]) { [modifiedRows addObject:self.expandIndexPath]; self.expandIndexPath = nil; } else { if (self.expandedIndexPath) [modifiedRows addObject:self.expandIndexPath]; self.expandIndexPath = indexPath; [modifiedRows addObject:indexPath]; } // This will animate updating the row sizes [tableView reloadRowsAtIndexPaths:modifiedRows withRowAnimation:UITableViewRowAnimationAutomatic]; // Preserve the deselection animation (if desired) [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; [tableView deselectRowAtIndexPath:indexPath animated:YES]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ViewControllerCellReuseIdentifier]; cell.textLabel.text = [NSString stringWithFormat:@"I'm cell %ld:%ld", (long)indexPath.section, (long)indexPath.row]; return cell; }