Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView's tableHeaderView height property is changed to strange values during load and rotation

I have a custom UIView which I set to the tableHeaderView property of a UITableView during loadView:

headerView = [[MYViewClass alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 120)];
[headerView sizeToFit];

self.tableView.tableHeaderView = headerView;

The view draws incorrectly, with part of the view clipped and white space above the table. When rotating the device the view almost disappears. On rotating back the view is now bigger that the space for the header and obscures some of the cells in the table.

To troubleshoot I have overrode the setFrame method in my custom view class:

- (void) setFrame:(CGRect)frame {
    [super setFrame:frame];
    NSLog(@"%@ - %@", NSStringFromSelector(_cmd), NSStringFromCGRect(frame));
}

I also put a break point on the NSLog statement so I could see what called the setFrame and I get some odd results that I can't explain and hope someone can shed some light on what is happening and why.

During loadView

1. initWithFrame calls: setFrame: - {{0, 0}, {320, 120}}
2. sizeToFit calls: setFrame: - {{0, 0}, {320, 109}}
3. setTableHeaderView calls:  setFrame: - {{0, 0}, {320, 109}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 109}}
5. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 65}}
6. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 65}}
7. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 65}}

Rotating the device left

1. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {480, 0}}
2. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {480, 0}}
3. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {480, 12}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {480, 12}}

Rotating the device right

1. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 172}}
2. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 172}}
3. _resizeWithOldSuperviewSize calls: setFrame: - {{0, 0}, {320, 160}}
4. _adjustTableHeaderAndFooterViews calls: setFrame: - {{0, 0}, {320, 160}}

Which explains why my view looks truncated initially, then almost disappears and finally ends up overlapping the cells. It appears that _resizeWithOldSuperviewSize is the culprit and what I don't understand is why it is being called and where it is getting these odd values from.

I have a really rubbish work around by calling [self.tableView.tableHeaderView sizeToFit] in viewDidAppear: and didRotateFromInterfaceOrientation: which puts the frame back to the correct size but the redrawing is awful as both happen after the view is visible or after the rotation animation. Trying to set this anytime before the view is visible causes _resizeWithOldSuperViewSize to set the frame back to these odd sizes.

like image 987
Magic Bullet Dave Avatar asked Feb 12 '12 10:02

Magic Bullet Dave


People also ask

How do I change the height of a header in Swift?

Step 1: Set the section header height as UITableView. automaticDimension. Step 2: In estimated height for header delegate assign an estimated value. Step 3: In view for header delegate add a UILabel and apply constraints relative to the returning UIView.

What is header view?

The header view is the first item to appear in the table's view's scrolling content, and it's separate from the header views you add to individual sections. The default value of this property is nil . When assigning a view to this property, set the height of that view to a nonzero value.


1 Answers

You need to get the intrinsic size and autoresizingMask right. Once you do that, UITableView will stop screwing with your tableHeaderView.

For example, if you want your header to have a fixed height which depends on its contents, but you want your header to use the entire table width, this is what you would do:

1.Create your view with the following Autoresizing mask configuration (so the table won't try to increase the header view height):

enter image description here
2. Add your subviews using AutoLayout so the top/bottom anchors match your view (this is so your subviews define the height of your header view)
3. Add your header view like so:

let headerView : CustomView? = CustomView.fromNib()
headerView?.sizeToFit()

tableView.tableHeaderView = headerView
like image 114
Cezar Signori Avatar answered Nov 10 '22 06:11

Cezar Signori