Skip to content

Instantly share code, notes, and snippets.

@brentsimmons
Created April 26, 2014 22:09
Show Gist options
  • Save brentsimmons/11332478 to your computer and use it in GitHub Desktop.
Save brentsimmons/11332478 to your computer and use it in GitHub Desktop.
UITableView header issues
#pragma mark - Class Methods
+ (BOOL)requiresConstraintBasedLayout {
return YES;
}
#pragma mark - Init
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (!self) {
return nil;
}
_imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cloud-logo"]];
_imageView.translatesAutoresizingMaskIntoConstraints = NO;
_imageView.contentMode = UIViewContentModeRedraw;
[_imageView setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[_imageView setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self addSubview:_imageView];
_label = [VSSyncUI descriptionLabel];
_label.translatesAutoresizingMaskIntoConstraints = NO;
_label.text = NSLocalizedString(@"Vesper automatically keeps your notes backed up and shared across your devices. Sign in or create an account to get started. We’ll take care of the rest.", @"");
_label.contentMode = UIViewContentModeRedraw;
[_label setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[_label setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self addSubview:_label];
[self setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[self setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
self.backgroundColor = [UIColor redColor];
self.translatesAutoresizingMaskIntoConstraints = NO;
return self;
}
#pragma mark - API
- (void)updateLabelWidth:(CGFloat)superviewWidth {
self.label.preferredMaxLayoutWidth = superviewWidth - (20.0f * 2.0f);
}
#pragma mark - Constraints
- (void)updateConstraints {
UIView *imageView = self.imageView;
UIView *label = self.label;
NSDictionary *bindings = NSDictionaryOfVariableBindings(imageView, label);
NSLayoutConstraint *constraintCenterX = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];
[self addConstraints:@[constraintCenterX]];
NSArray *labelHorizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-20-[label]-20-|" options:0 metrics:nil views:bindings];
[self addConstraints:labelHorizontalConstraints];
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[imageView]-20-[label]-20-|" options:0 metrics:nil views:bindings];
[self addConstraints:verticalConstraints];
[super updateConstraints];
}
UITableViewHeaderFooterView *headerView = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:nil];
CGRect appFrame = [UIScreen mainScreen].applicationFrame;
VSSyncNoAccountHeaderView *headerViewContentView = [[VSSyncNoAccountHeaderView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(appFrame), 400.0)];
headerViewContentView.translatesAutoresizingMaskIntoConstraints = NO;
[headerViewContentView updateLabelWidth:CGRectGetWidth(appFrame)];
[headerViewContentView setNeedsUpdateConstraints];
[headerViewContentView updateConstraintsIfNeeded];
// CGSize bestSize = [headerViewContentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
//// bestSize.height += 20.0;
// headerViewContentView.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(appFrame), bestSize.height);
[headerView.contentView addSubview:headerViewContentView];
self.tableView.tableHeaderView = headerView;
@Inferis
Copy link

Inferis commented Apr 26, 2014

Yes, but it's possible that updateConstraints is called more than once (not sure this is happening here though). So you're add the same constraints each time updateConstraints is called.

@Inferis
Copy link

Inferis commented Apr 26, 2014

Additionally: autolayout doesn't care about subviews and their sizes even if you applied constraints to them. You need to override intristicContentSize in the headerView class or set the dimensions to your instance manually.

@kylesluder
Copy link

Where do you add the constraints that relate headerViewContentView to its superview? The only constraints you create deal with the subviews of the VSSyncNoAccountHeaderView.

@brentsimmons
Copy link
Author

@kylesluder -- I did add those later. It didn’t actually help, though it changed the results slightly.

@ericallam
Copy link

What does the implementation of -tableView:heightForHeaderInSection: look like? Are you returning the correct height from that? Could be an issue not with setting the correct size of the header view, but an incorrect content size on the table view's scroll view.

@an0
Copy link

an0 commented Apr 28, 2014

As pointed out by others above:

  1. You need constrain headerViewContentView relative to headerView.contentView.
  2. You didn't show your -tableView:heightForHeaderInSection:.

I also want to add that you'd better offer a minimum reproducible sample project so we don't need to guess what you did or not, right or wrong.

@winkelsdorf
Copy link

@brentsimmons Did you ever come up with a solution to this? I am currently trying to subclass UITableViewHeaderFooterView in order to display my own multi-line UILabel. It's just a mess, spent several hours with AutoLayout and Reveal debugging this.. UITableViewAutomaticDimension should work, the contentView has the correct size. But instead it sits on top of the 1st section cell which it overlaps.

@InfiniteCode
Copy link

@winkelsdorf Were you able to solve this on your side?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment