I am trying to find the cleanest way to adjust the height of my UITableView tableHeaderView, which in itself is a multi-line label view. It seems that the self-timer should be able to easily determine the height.
I create a shortcut as follows:
DDInsetLabelView *header = [[DDInsetLabelView alloc] initWithFrame:CGRectZero]; header.insets = UIEdgeInsetsMake(10.f, 10.f, 10.f, 10.f); header.label.text = [NSString stringWithFormat:@"%@\n%@", self.categoryTitle, self.subcategoryTitle]; header.label.numberOfLines = 0; header.label.textAlignment = NSTextAlignmentCenter; self.tableView.tableHeaderView = header;
inside the label class, I handle the layout as follows:
- (void)updateConstraints { [super updateConstraints]; NSDictionary *metrics = @{@"t": @(self.insets.top), @"l": @(self.insets.left), @"b": @(self.insets.bottom), @"r": @(self.insets.right)}; NSDictionary *views = NSDictionaryOfVariableBindings(_label); self.label.translatesAutoresizingMaskIntoConstraints = NO; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(t)-[_label]-(b)-|" options:0 metrics:metrics views:views]]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(l)-[_label]-(r)-|" options:0 metrics:metrics views:views]]; } - (void)layoutSubviews { [super layoutSubviews]; self.label.preferredMaxLayoutWidth = self.label.frame.size.width; [super layoutSubviews]; }
Now, here is how I calculate the height for the header in my controller:
- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; UIView *header = self.tableView.tableHeaderView; NSLayoutConstraint *headerWidthConstraint = [NSLayoutConstraint constraintWithItem:header attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:header.frame.size.width]; [header addConstraint:headerWidthConstraint]; CGFloat height = [header systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height; [header removeConstraint:headerWidthConstraint]; header.frame = CGRectMake(0, 0, header.frame.size.width, height); header.translatesAutoresizingMaskIntoConstraints = YES; self.tableView.tableHeaderView = header; }
This seems to work fine visually, but I keep getting the following error in the console:
Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSLayoutConstraint:0x7fb2e5bb7540 'UIView-Encapsulated-Layout-Height' V:[DDInsetLabelView:0x7fb2e5b53250(0)]>", "<NSLayoutConstraint:0x7fb2e5bb84b0 V:|-(10)-[UILabel:0x7fb2e5b65200'Custom Box\nCustomize with...'] (Names: '|':DDInsetLabelView:0x7fb2e5b53250 )>", "<NSLayoutConstraint:0x7fb2e5bb8500 V:[UILabel:0x7fb2e5b65200'Custom Box\nCustomize with...']-(10)-| (Names: '|':DDInsetLabelView:0x7fb2e5b53250 )>" )
I assume that UIView-Encapsulated-Layout-Height represents some internally calculated height value for the header. How can I avoid this warning when using autostart to calculate the height of my header?