I\'m having trouble resizing a tableHeaderView. It simple doesn\'t work.
1) Create a UITableView and UIView (100 x 320 px);
2) Set the UIView as tableHeaderV
This answer is old and apparently doesn't work on iOS 7 and above.
I ran into the same problem, and I also wanted the changes to animate, so I made a subclass of UIView for my header view and added these methods:
- (void)adjustTableHeaderHeight:(NSUInteger)newHeight{
NSUInteger oldHeight = self.frame.size.height;
NSInteger originChange = oldHeight - newHeight;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0f];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
self.frame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
newHeight);
for (UIView *view in [(UITableView *)self.superview subviews]) {
if ([view isKindOfClass:[self class]]) {
continue;
}
view.frame = CGRectMake(view.frame.origin.x,
view.frame.origin.y - originChange,
view.frame.size.width,
view.frame.size.height);
}
[UIView commitAnimations];
}
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
[(UITableView *)self.superview setTableHeaderView:self];
}
This essentially animates all the subviews of the UITableView that aren't the same class type as the calling class. At the end of the animation, it calls setTableHeaderView on the superview (the UITableView) – without this the UITableView contents will jump back the next time the user scrolls. The only limitation I've found on this so far is if the user attempts to scroll the UITableView while the animation is taking place, the scrolling will animate as if the header view hasn't been resized (not a big deal if the animation is quick).
If your tableHeaderView is a content adjustable webView,you can try:
[self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
self.webView.height = self.webView.scrollView.contentSize.height;
self.tableView.tableHeaderView = self.webView;
}
I tested it on iOS9 and iOS11,worked well.
Setting the height for header view property tableView.tableHeaderView
in viewDidLoad
seems not work, the header view height still not change as expected.
After fighting against this issue for many tries. I found that, you can change the height by invoking the header view create logic inside the
- (void)didMoveToParentViewController:(UIViewController *)parent
method.
So the example code would look like this:
- (void)didMoveToParentViewController:(UIViewController *)parent {
[super didMoveToParentViewController:parent];
if ( _tableView.tableHeaderView == nil ) {
UIView *header = [[[UINib nibWithNibName:@"your header view" bundle:nil] instantiateWithOwner:self options:nil] firstObject];
header.frame = CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), HeaderViewHeight);
[_tableView setTableHeaderView:header];
}
}
FYI: I've gotten this to work by modifying the tableHeaderView and re-setting it. In this case, i'm adjusting the size of the tableHeaderView when the UIWebView subview has finished loading.
[webView sizeToFit];
CGRect newFrame = headerView.frame;
newFrame.size.height = newFrame.size.height + webView.frame.size.height;
headerView.frame = newFrame;
[self.tableView setTableHeaderView:headerView];
I think it should work if you just set the height of myHeaderView like so:
CGRect newFrame = myHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
myHeaderView.frame = newFrame;
self.tableView.tableHeaderView = myHeaderView;
Its because the setter of tableHeaderView.
You have to set the UIView height before set the tableHeaderView. (Would be much easier if Apple open sources this framework...)