Reputation: 11543
How can I modify the height of a header section accordantly to the view I'm adding it?
heightForHeaderInSection
is called before viewForHeaderInSection
and I don't know the view size until I create it.
Upvotes: 5
Views: 8195
Reputation: 2734
To force calling heightForHeaderInSection method, you just need to call both methods beginUpdates/endUpdates of the UITableView.
First create and init a variable height and return it
var height: CGFloat = 160.0
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return height
}
Then add a method that will update the section height with a new value
func updateHeaderHeight(newHeight: CGFloat) {
tableView.beginUpdates()
height = newHeight
tableView.endUpdates()
}
Upvotes: 1
Reputation: 586
You can follow this:
heightForHeaderInSection
" itself.heightForHeaderInSection
".Upvotes: 12
Reputation: 307
This also works:
Override estimatedHeightForHeaderInSection
, return a CGFloat
, whatever, but not 0.
Create a CGFloat
property to save the height for header view.
var sectionHeaderViewHeight:CGFloat = 10.0
(The value is not important, but never set to 0.0
, if you do this, viewForHeaderInSection
will never be invoked, you will never have a section header view!)
Override heightForHeaderInSection
and return that property.
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return sectionHeaderViewHeight
}
Create the header view in viewForHeaderInSection
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
//configuration your view
//.....
return headerView
}
This is the key step: Add these code before return headerView
.
self.tableView.beginUpdates()
sectionHeaderViewHeight = //The value you would like to set
self.tableView.endUpdates()
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
//configuration your view
//.....
//----Key Steps:----
self.tableView.beginUpdates()
sectionHeaderViewHeight = //The value you would like to set
self.tableView.endUpdates()
//----Key Steps----
return headerView
}
var sectionHeaderViewHeight:CGFloat = 10.0
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return sectionHeaderViewHeight
}
Upvotes: 3
Reputation: 437381
Yeah, it seems strange/redundant that you have to create both the view and then also determine the size of that view as a completely separate event, but you can minimize the silliness by moving some of that shared logic into some shared method. E.g., you probably have to figure out the size of the view at some point during it's creation, so move that logic to some shared method.
For example, I have logic that I use for determining the size of the UILabel I'm putting in my header based upon the size of the text. So I pulled that out of my viewForHeaderInSection
and moved it into my own method, sizeForHeaderLabelInSection
, which I use to determine the size of my label control):
- (CGSize)tableView:(UITableView *)tableView sizeForHeaderLabelInSection:(NSInteger)section
{
NSString *text = [self tableView:tableView titleForHeaderInSection:section];
CGSize constraint = CGSizeMake(self.view.frame.size.width - kSectionTitleLeftMargin - kSectionTitleRightMargin, kMaxSectionTitleHeight);
return [text sizeWithFont:[self fontForSectionHeader] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
}
Then, I modified the standard heightForHeaderInSection
to use that method, adding, of course, my top and bottom margin around my UILabel:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return [self tableView:tableView sizeForHeaderLabelInSection:section].height + kSectionTitleTopMargin + kSectionTitleBottomMargin;
}
And then I modified the standard viewForHeaderInSection
to also use this sizeForHeaderLabelInSection
, too:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
CGSize size = [self tableView:tableView sizeForHeaderLabelInSection:section];
UIView* headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, size.width + kSectionTitleLeftMargin + kSectionTitleRightMargin, size.height + kSectionTitleTopMargin + kSectionTitleBottomMargin)];
//headerView.contentMode = UIViewContentModeScaleToFill;
// Add the label
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(kSectionTitleLeftMargin,
kSectionTitleTopMargin,
size.width,
size.height)];
// put stuff to set up my headerLabel here...
[headerView addSubview:headerLabel];
// Return the headerView
return headerView;
}
Clearly, how you do this is completely up to you and what you're trying to achieve. But I think you'll have success if you shift your mindset from "how do I figure out the size of that view I created in viewForHeaderInSection
" to "how can I move the the code that I used for determining the size in viewForHeaderInSection
into some common method that my heightForSectionInHeader
can use, too.
Upvotes: 3