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

4

19

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;
    }
}
Viola answered 17/4, 2010 at 18:1 Comment(0)
S
26

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;
}
Schadenfreude answered 21/4, 2010 at 17:48 Comment(5)
thanks @Schadenfreude that worked well. it wasn't able to remove the view however (which is what i was trying to do). but as soon as i scrolled it was removed, so thats ok :)Furey
for anyone who has the same use case as me (they want to remove the view), you can keep a reference to it and use the method removeFromSuperview on it during the animation to hide it properly.Furey
This works well, but the area that pops down covers my first UITableViewCell. Any ideas? Any way to shift the tableView down when this happens?Kingsbury
This worked for me, except it didn't follow the animation duration that I had set up with [UIView beginAnimations:context:]Grethel
Guys, where to put this method (changeHeight:). I need to auto animation, when headers is appear. How to call it?Snob
C
12

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];
Cyclic answered 29/10, 2010 at 13:4 Comment(0)
B
2

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()
        } )
    }
}
Bumper answered 6/7, 2015 at 14:30 Comment(0)
M
-1

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.

Marrin answered 21/4, 2010 at 12:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.