1

This question is connected to the following question: Can you animate a height change on a UITableViewCell when selected?

I am animating the height change of the UITableViewCell explained in that question by using the following code:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


    ProductCell *cell = (ProductCell *) [tableView cellForRowAtIndexPath:indexPath];

    // Deselect cell
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    // Toggle 'selected' state
    BOOL isSelected = ![self cellIsSelected:indexPath];


    // Store cell 'selected' state keyed on indexPath
    NSNumber *selectedIndex = [NSNumber numberWithBool:isSelected];
    [self.selectedIndexes setObject:selectedIndex forKey:indexPath];


    if (isSelected) {

        cell.addButton.hidden = NO;

    }else {


        cell.addButton.hidden = YES;

   }

    // This is where magic happens...
    [self.theMenuListTableView beginUpdates];

    [self.theMenuListTableView endUpdates];

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // If our cell is selected, return double height
    if([self cellIsSelected:indexPath]) {
        return kCellHeight * 2.0;
    }

    // Cell isn't selected so return single height
    return kCellHeight;
}

- (BOOL)cellIsSelected:(NSIndexPath *)indexPath {

    NSNumber *selectedIndex = [self.selectedIndexes objectForKey:indexPath];
    return selectedIndex == nil ? FALSE : [selectedIndex boolValue];
}

This is working fine, but want I want is, that when one cell is clicked and the height has been animated, and I then click on another cell, I want the first cell to contract/collapse to it's original size and the other to expand (animate the height change). How can I do this?

Community
  • 1
  • 1

3 Answers3

1

When you select a cell, and it s animated, store the cell's indexPath. When you click an another cell, check is it the same cell or the indexPath is different. Write a method which will make the other animation . If you have a stored indexPath then call that new method for the cell with that stored indexPath. I hope it helps.

Magyar Miklós
  • 4,182
  • 2
  • 24
  • 42
1

Maybe that helps:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                   reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.text = [NSString stringWithFormat:@"%d",indexPath.row];
    cell.selectionStyle = UITableViewCellEditingStyleNone;
    return cell;
}

- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 3;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationMiddle];

    if (indexPath.row > 0) {
        NSIndexPath *path = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
        [tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationNone];
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // If our cell is selected, return double height
    if([self cellIsSelected:indexPath]) {
        return 40 * 2.0;
    }

    // Cell isn't selected so return single height
    return 40;
}

- (BOOL)cellIsSelected:(NSIndexPath *)indexPath {
    return (tblView.indexPathForSelectedRow.row == indexPath.row);
}
likeitlikeit
  • 5,563
  • 5
  • 42
  • 56
Josshad
  • 894
  • 7
  • 14
  • This solution is really good, because it is much more simple.. but under iOS 7, this results in disappearing separator lines. – Marc Sep 17 '13 at 18:43
1

So i guess you are saving selected indexes in a NSDictionary object, and for every indexPath you save state (Selected/Not Selected). What you need to do is to save only 1 cell's index, the selected one.

So, basically need the following changes :

  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


ProductCell *cell = (ProductCell *) [tableView cellForRowAtIndexPath:indexPath];

// Deselect cell
[tableView deselectRowAtIndexPath:indexPath animated:NO];

if (![indexPath isEqual:selectedIndex]) {

    cell.addButton.hidden = NO;

   // Store cell 'selected' state keyed on indexPath
   selectedIndex = indexPath;

}else {
    //Click deselecting cell
    selectedIndex = nil;

    cell.addButton.hidden = YES;

  }

// This is where magic happens...
[self.theMenuListTableView beginUpdates];

[self.theMenuListTableView endUpdates];

   }

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // If our cell is selected, return double height
    if(selectedIndex != nil && [selectedIndex isEqual:indexPath]) {
        return kCellHeight * 2.0;
    }

    // Cell isn't selected so return single height
    return kCellHeight;
}

//- (BOOL)cellIsSelected:(NSIndexPath *)indexPath {
//
//    NSNumber *selectedIndex = [self.selectedIndexes objectForKey:indexPath];
//    return selectedIndex == nil ? FALSE : [selectedIndex boolValue];
//}

and add to .h file of your Controller

@property NSIndexPath * selectedIndex;

and to .m

@synthetize selectedIndex;

i could check if this code runs, so try it and see if it is the solution for you.

Eugen Halca
  • 1,775
  • 2
  • 13
  • 26