The UITableView tableHeaderView height property changes to strange values ​​during loading and rotation

I have a custom UIView that I set for the tableHeaderView property of the UITableView during loadView:

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

The view is not drawn correctly, with part of the cropped and white space above the table. When the device rotates, the view almost disappears. When you turn back, the view is now larger than the heading space and hides some cells in the table.

To troubleshoot, I overridden the setFrame method in my custom view class:

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

I also set a breakpoint in the NSLog statement so that I can see what is called setFrame, and get some odd results that I cannot explain, and hope someone can shed 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}} 

Rotate 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}} 

Rotate device to the 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}} 

This explains why my gaze first looks truncated, and then almost disappears and finally ends with overlapping cells. It seems that _resizeWithOldSuperviewSize is the culprit, and I don't understand why it is being called and where it gets these odd values ​​from.

I have a very difficult job calling [self.tableView.tableHeaderView sizeToFit] in viewDidAppear: and didRotateFromInterfaceOrientation: which will return the frame to the correct size, but the redrawing is terrible as both happen after the view is visible or after the rotation animation, Trying to set this to any time before the visible view calls _resizeWithOldSuperviewSize to return the frame to these odd sizes.

+4
source share
4 answers

You need to get the inner size and auto-resistant mask. Once you do this, the UITableView will stop screwing with tableHeaderView.

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

1.Create your view with the following Autoresizing mask configuration (so the table will not try to increase the height of the header view):

enter image description here
2. Add your subviews with AutoLayout so that the top / bottom bindings match your view (this means that your subviews determine the height of your title)
3. Add your title like this:

 let headerView : CustomView? = CustomView.fromNib() headerView?.sizeToFit() tableView.tableHeaderView = headerView 
+3
source

This will help you read the Apple sizing scheme using the autoresizingMask UIView . Possible values:

 enum { UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 << 0, UIViewAutoresizingFlexibleWidth = 1 << 1, UIViewAutoresizingFlexibleRightMargin = 1 << 2, UIViewAutoresizingFlexibleTopMargin = 1 << 3, UIViewAutoresizingFlexibleHeight = 1 << 4, UIViewAutoresizingFlexibleBottomMargin = 1 << 5 }; typedef NSUInteger UIViewAutoresizing; 

I have no doubt that after some experimentation you will find a suitable combination of a scaling mask to solve your problem.

Also note that sizeToFit , according to the same documentation source, resizes and moves the view of the receiver, so it just closes its routines. "It seems impractical to call this immediately after creating the view and before placing it in the table header.

+2
source

It turns out exactly the same problem when I wanted to have a table header view with SearchBar and some user interface below. The funny thing is that if you only hold the SearchBar, it works just fine.

So, I decided to apply a really dirty hack by resetting the frame height in the overridden frameset of your custom UIView (there you register the frame size) to something you need (in your case it is 120).

 - (void) setFrame:(CGRect)frame { frame.Height = 120; [super setFrame:frame]; } 

After that, there is no weird title and table overlap during rotation. Hope this helps.

PS BTW I use Auto Layout inside my custom UIView.

+1
source

Create a new xib file and adjust the size in the xib file. Let's say xib is called customHeader (.xib) Declare:

  IBOutlet UIView *customView; 

Assign customView to this view in xib.

  -(UIView *)viewOfCategory; 

In .m:

  -(UIView *)viewOfCategory { if (!customView) { [[NSBundle mainBundle] loadNibNamed:@"customHeader" owner:self options:nil]; } return customView; } 

Then call this UITableView method:

  -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection: (NSInteger)section { return [self customView]; } 

WHAT FINALLY AND MOST IMPORTANT THAT YOUR QUESTION WILL ANSWER! Implement this other UITableView method:

  -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { // You can just return default size of your xib: return [[self viewOfCategory] bounds].size.height; // Or you can return custom size using CGRect or whatever. } 
-3
source

Source: https://habr.com/ru/post/1396021/


All Articles