5

I want to animate a UITableViewCell like in the following image (The cell gets resized smaller) before detailedViewController is show. I have tried it from last two days and tried other all the answers I found for similar questions.

I want the cell to animate/resize as soon as user put his finger on the UITableViewCell.

enter image description here

The UITableViewCell is a custom cell. I have tried setting a new frame to cell.contentView in UITableViewCell subclass's setSelected:(BOOL)selected animated:(BOOL)animated method. The UITableViewCell didn't resize as I expected.

What I have also observed is this method is called when user lifts his finger up from the UITableViewCell. Actually I want it to happen as soon as user taps the cell. And if the cell is not selected and user moves to some other cell, cell should get resized back to normal size.

Then I did some searching on receiving touch events from UITableViewCell. And I tried to add a UILongPressGestureRecognizer and UITapGestureRecognizer and in the selector I tried to change cell.contentView frame like this

cell.contentView.frame = CGRectMake(cell.frame.origin.x +20, cell.frame.origin.y, cell.frame.size.width-20, cell.frame.size.height);
[cell setNeedsDisplay];

But the selected cell is only flashing(cell background) it is not resizing as I expected.

Any suggestions would be really helpful. Thanks in advance

Bhavesh Nayi
  • 3,626
  • 1
  • 27
  • 42
Priyatham51
  • 1,864
  • 1
  • 16
  • 24

4 Answers4

5

Here is an simpler way to da cell animation on tap in Swift 5.0:

func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath)
{
    let cell = tableView.cellForRow(at: indexPath)

    UIView.animate(withDuration: 0.3) {

        cell!.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
    }
}

func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath)
{
    let cell = tableView.cellForRow(at: indexPath)

    UIView.animate(withDuration: 0.3) {

        cell!.transform = .identity
    }
}
Serge
  • 2,031
  • 3
  • 33
  • 56
2

Okay After reading through some doc and Going through WWDC videos's I was able to solve this.

I have learned a important thing.

Never use setFrame: on a view with AutoLayoutEnabled.

Keeping that in mind I changed my Custom UITableViewCell xib to use AutoResizing masks. And then in my UITableViewController I used these tableView:didHighlightRowAtIndexPath: tableView:didUnHighlightRowAtIndexPath: delegates

Here is the code snippet from my view Controller.

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

        NSLog(@"I'm Highlighted at %ld",(long)indexPath.section);
        CustomTableViewCell *cell = (CustomTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];

        originalCellSize = cell.frame;

//Using animation so the frame change transform will be smooth.

        [UIView animateWithDuration:0.1f animations:^{

            cell.frame = CGRectMake(cell.frame.origin.x +20, cell.frame.origin.y, cell.frame.size.width-40, cell.frame.size.height);
        }];

    }


    -(void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
    {
        CustomTableViewCell *cell = (CustomTableViewCell *)[self.tableableView cellForRowAtIndexPath:indexPath];


        [UIView animateWithDuration:0.1f animations:^{
            cell.frame = CGRectMake(0, originalCellSize.origin.y, self.view.bounds.size.width, 180) ;
        }];

        originalCellSize = CGRectMake(0, 0, 0, 0);
    }
Priyatham51
  • 1,864
  • 1
  • 16
  • 24
2

I was trying to achieve something similar to you. I was trying to show a portion of my UIImage in a UIImageView that I had added to my custom UITableViewCell, and had set the constraints to have my imageview the whole size of the cell (Similar to background, especially as you have a custom cell as well). I followed the answer @Joy had provided for this question, and created the following:

I added this to my viewDidLoad:

self.currentSelection = -1;
// I changed his line below, so that the image resizing (cell resizing really) is constant for 
//all my images. I guess you can use this to resize your background back and forth to whatever size you want to.
self.newCellHeight = self.tableView.frame.size.width*3/2;

Then I added these:

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

//I added this to toggle a tap-tapagain kind of thing, so if the same cell is tapped twice, first tap expands and second tap collapses.  
    if (self.currentSelection==indexPath.row) {
        self.currentSelection = -1;
    }else{
        self.currentSelection = indexPath.row;
    }
        // save height for full text label
//    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];

}
//The rest is pretty much the same as his code
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
    // do things with your cell here

    // sentinel
    self.currentSelection = -1;

    // animate
    [tableView beginUpdates];
    [tableView endUpdates];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    int rowHeight;
    if ([indexPath row] == self.currentSelection) {
        rowHeight = self.newCellHeight;
    } else rowHeight = 100;
    return rowHeight;
}

One last thing, if you want to show the background to be centred, and to 'zoom' in and out from center. I'd set my imageview content mode to center, something like this:

[cell.myImageView setContentMode:UIViewContentModeCenter];

I learned a lot from @EmptyStack and @erkanyildiz answers to this question.

Anyway, I hope this helped in anyway, and sorry if none of it was relevant! :)

Community
  • 1
  • 1
Septronic
  • 1,156
  • 13
  • 32
-1

Try this

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath)path
// or it must be some other method
{
  [self.tableView beginUpdates];
  [[self.tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:rowAnimation];
  [self.tableView endUpdates];
}

In your table view delegate methods you must know which cell is selected.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath)path
{
  YourTableClass *cell=[tableView cellForRowAtIndexPath:path];
  if(cell.isTaped)
    return increasedHeight;
  else
    return defaultHeight;
} 
Daniyar
  • 2,975
  • 2
  • 26
  • 39
  • didSelectRowAtIndexPath gets called when the user lifts his finger back from the screen. I even tried willSelectRowAtIndexPath. It is not notifying me as soon as it received the tap. – Priyatham51 Oct 31 '14 at 14:02
  • 2
    Calling cellForRowForAtIndexPath in heightForRowAtIndexPath will crash your program. See this http://stackoverflow.com/a/12653203/1032179 – Salman Hasrat Khan Jul 10 '15 at 20:23