简体   繁体   中英

How to animate the height change of an section header in UITableView?

I've implemented this method to return the section header height. However, when the height for the section changes, it happens immediately without animation.

Is there an animation for that?

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (flatHeader) {
        return 50.0f;
    } else {
        return 100.0f;
    }
}

I'm not 100% sure this will work for a table header but it works for table rows so it's worth a shot. I have an instance variable headerHeight initially set to 44.0 and I change it as so:

- (void)changeHeight {
    [self.tableView beginUpdates];
    headerHeight = 88.0;
    [self.tableView endUpdates];
}

In my code I return the headerHeight in heightForRowAtIndexPath but you can try it in heightForHeaderInSection :

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return headerHeight;
}

This works:

flatHeader = YES;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[[self tableView] beginUpdates];
[[self tableView] endUpdates];
CGRect frame = [[self headerView] frame];
frame.size.height = [self tableView:[self tableView] heightForHeaderInSection:0];
[[self headerView] setFrame:frame];
[UIView commitAnimations];

My solution in Swift:

class MyTableViewController: UITableViewController {

var sectionHeaderView:UIView?

...

override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    sectionHeaderView = UIView(frame: CGRectMake(0, 0, self.tableView.frame.size.width, 30))
    sectionHeaderView?.backgroundColor = UIColor.grayColor()

    var button = UIButton(frame: CGRectMake(0, 0, self.tableView.frame.size.width, 30))
    button.backgroundColor = UIColor.darkGrayColor()
    button.setTitle("collapse/expand", forState: .Normal)
    button.addTarget(self, action: "collapseOrExpandSectionHeader", forControlEvents: .TouchUpInside)

    sectionHeaderView?.addSubview(button)

    return sectionHeaderView
}

...

override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

    if let sectionHeader = sectionHeaderView {
        return view.frame.size.height
    } else {
        return 30.0
    }
}

...

func collapseOrExpandSectionHeader() {

    if let sectionHeader = sectionHeaderView {

        let headerHeight:CGFloat

        if sectionHeader.frame.size.height == 200 {
            headerHeight = 30.0
        } else {
            headerHeight = 200.0
        }

        UIView.animateWithDuration(0.3, animations: {
            self.tableView?.beginUpdates()
            sectionHeader.frame.size.height = headerHeight
            self.tableView?.endUpdates()
        } )
    }
}

I haven't tested this, but sometimes I get unwanted animations when my UITableViewCells change height. The cause of this is that I draw my own cells, and I use CALayers to do so. In the cell's (void)layoutSubviews I would change the size of my CALayer to be the size of the frame for the cell

myLayer.frame = self.bounds;

When the frame/bounds property of a CALayer changes, it is animated. So in theory, I would say that you could use the method tableView:viewForHeaderInSection: which would allow you to draw your own section header. You could just return a UIView that implements (void)layoutSubviews and then in that method do

self.layer.frame = self.bounds;

Just an idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM