Unfortunately, table header views cannot be sized using auto layout. You can use auto layout for elements inside the header but you have to specify the header's size by explicitly setting its frame. If the header's height is static and known at compile time you can use IB. However, if the height is dynamic or depends on the device (as in your case), you have to set it in code.
A quite flexible solution would be to create a custom subclass of UITableView and adapt the header's frame in the layoutSubviews method. This way the header's size gets automatically adjusted when the table view is resized. You have to be careful, however, to only re-apply the header's frame when a change is actually needed to avoid an infinite loop.
Here's what it would look like in Objective-C:
@interface MyTableView : UITableView
@end
@implementation MyTableView : UITableView
- (void)layoutSubviews {
[super layoutSubviews];
if (self.tableHeaderView) {
UIView *header = self.tableHeaderView;
CGRect rect = CGRectMake(0, 0, self.bounds.size.width,
self.bounds.size.height / 2);
// Only adjust frame if needed to avoid infinite loop
if (!CGRectEqualToRect(self.tableHeaderView.frame, rect)) {
header.frame = rect;
// This will apply the new header size and trigger another
// call of layoutSubviews
self.tableHeaderView = header;
}
}
}
@end
The Swift version looks like this:
class MyTableView: UITableView {
override func layoutSubviews() {
super.layoutSubviews()
if let header = tableHeaderView {
let rect = CGRectMake(0, 0, bounds.size.width, bounds.size.height / 2)
// Only adjust frame if needed to avoid infinite loop
if !CGRectEqualToRect(header.frame, rect) {
header.frame = rect
// This will apply the new header size and trigger
// another call of layoutSubviews
tableHeaderView = header
}
}
}
}
Note that the above snippets use the bounds of the table view rather than the screen size to calculate the header size.
Update: Note that sometimes an additional call to layoutIfNeeded is needed after setting the tableHeaderView property. I ran into an issue where section headers were drawn above the header view without calling layoutIfNeeded.
yourOutlet.constant=[[UIScreen mainScreen] bounds].size.height/2. On rotation, you will need to also reset the constant.