Can you animate a height change on a UITableViewCell when selected?

前端 未结 21 1022
天涯浪人
天涯浪人 2020-11-22 04:41

I\'m using a UITableView in my iPhone app, and I have a list of people that belong to a group. I would like it so that when the user clicks on a particular pers

相关标签:
21条回答
  • 2020-11-22 04:58

    I used @Joy's awesome answer, and it worked perfectly with ios 8.4 and XCode 7.1.1.

    In case you are looking to make your cell toggle-able, I changed the -tableViewDidSelect to the following:

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    //This is the bit I changed, so that if tapped once on the cell, 
    //cell is expanded. If tapped again on the same cell, 
    //cell is collapsed. 
        if (self.currentSelection==indexPath.row) {
            self.currentSelection = -1;
        }else{
            self.currentSelection = indexPath.row;
        }
            // animate
            [tableView beginUpdates];
            [tableView endUpdates];
    
    }
    

    I hope any of this helped you.

    0 讨论(0)
  • 2020-11-22 04:58

    I just resolved this problem with a little hack:

    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 expand the cell height I set isInEdit = YES and call the method [self onTimer] and it animates the cell growth until it reach the s_CellHeightEditing value :-)

    0 讨论(0)
  • 2020-11-22 04:59

    Add a property to keep track of the selected cell

    @property (nonatomic) int currentSelection;
    

    Set it to a sentinel value in (for example) viewDidLoad, to make sure that the UITableView starts in the 'normal' position

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    
        //sentinel
        self.currentSelection = -1;
    }
    

    In heightForRowAtIndexPath you can set the height you want 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 you save the current selection and save a dynamic height, if required

    - (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];
        }
    }
    

    In didDeselectRowAtIndexPath set the selection index back to the sentinel value and animate the cell back to normal form

    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {       
            // do things with your cell here
    
            // sentinel
            self.currentSelection = -1;
    
            // animate
            [tableView beginUpdates];
            [tableView endUpdates];
        }
    }
    
    0 讨论(0)
  • 2020-11-22 04:59

    I don't know what all this stuff about calling beginUpdates/endUpdates in succession is, you can just use -[UITableView reloadRowsAtIndexPaths:withAnimation:]. Here is an example project.

    0 讨论(0)
  • 2020-11-22 04:59

    Yes It's Possible.

    UITableView has a delegate method didSelectRowAtIndexPath

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [UIView animateWithDuration:.6
                              delay:0
             usingSpringWithDamping:UIViewAnimationOptionBeginFromCurrentState
              initialSpringVelocity:0
                            options:UIViewAnimationOptionBeginFromCurrentState animations:^{
    
                                cellindex = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
                                NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
                                [violatedTableView beginUpdates];
                                [violatedTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationAutomatic];
                                [violatedTableView endUpdates];
                            }
                         completion:^(BOOL finished) {
        }];
    }
    

    But in your case if the user scrolls and selects a different cell then u need to have the last selected cell to shrink and expand the currently selected cell reloadRowsAtIndexPaths: calls heightForRowAtIndexPath: so handle accordingly.

    0 讨论(0)
  • 2020-11-22 05:01

    Instead of beginUpdates()/endUpdates(), the recommended call is now:

    tableView.performBatchUpdates(nil, completion: nil)
    

    Apple says, regarding beginUpdates/endUpdates: "Use the performBatchUpdates(_:completion:) method instead of this one whenever possible."

    See: https://developer.apple.com/documentation/uikit/uitableview/1614908-beginupdates

    0 讨论(0)
提交回复
热议问题