Reputation: 23053
First of all this ain't about dynamic cell's height. So don't mix it up.
I have a scenario in that I created three cards
Below are screens for above cards:
View hierarchy for above screens:
- Controller
- ScrollView
- Card-1
- Card-2
- Card-3 <---- We are interested in this card
- Custom View
- TableView
So I'm showing the constraints for last card here, all above card works perfect! and there is no constraints ambiguity or warnings.
Let's go through code:
First Add Card-3
to ScrollView
: here chartBox
is Card-2 and bottomBox
is Card-3
[self.scrollView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:[chartBox(200)]-(10)-[bottomBox]"
options:0
metrics:nil
views:@{@"bottomBox" : self.bottomBox, @"chartBox" : self.chartBox}]];
// Below constraint pin to increase content-size
[self.scrollView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:[bottomBox]-(10)-|"
options:0
metrics:nil
views:@{@"bottomBox" : self.bottomBox}]];
[self.scrollView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:[bottomBox]-(10)-|"
options:0
metrics:nil
views:@{@"bottomBox" : self.bottomBox}]];
Second add CustomView
to Card-3
: Here bluePrintView
is CustomView
_bluePrintView = [[BluePrintView alloc] init];
self.bluePrintView.translatesAutoresizingMaskIntoConstraints = NO;
[self.bottomBox addSubview:self.bluePrintView];
[self.bottomBox addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[bluePrintView]|" options:0 metrics:nil views:@{@"bluePrintView":self.bluePrintView}]];
[self.bottomBox addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[bluePrintView]|" options:0 metrics:nil views:@{@"bluePrintView":self.bluePrintView}]];
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width - 20;
NSDictionary *metrices = @{@"width" : [NSNumber numberWithFloat:screenWidth]};
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[bottomBox(width)]" options:0 metrics:metrices views:@{ @"bottomBox": self.bottomBox}]];
Third add TableView
to CustomView
:
self.tableView.tableFooterView = [[UIView alloc] init];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tableView]|" options:0 metrics:nil views:@{@"tableView":self.tableView}]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[tableView]|" options:0 metrics:nil views:@{@"tableView":self.tableView}]];
// Height constraint
CGFloat viewHeight = self.bounds.size.height;
self.tableHeightConstraint = [NSLayoutConstraint constraintWithItem:self.tableView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:viewHeight];
[self addConstraint:self.tableHeightConstraint];
[self.tableView addObserver:self forKeyPath:@"contentSize" options:0 context:NULL];
And in observer method I'll update tableHeightConstraint
constraint.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
self.tableHeightConstraint.constant = self.tableView.contentSize.height;
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
}
After trying all possibilities end up here. Warnings for constraints.
(
"<NSLayoutConstraint:0x7fbeb1e7e8e0 V:|-(0)-[UITableView:0x7fbeb2843000] (Names: '|':BluePrintView:0x7fbeb1e7ac30 )>",
"<NSLayoutConstraint:0x7fbeb1e7e700 V:[UITableView:0x7fbeb2843000]-(0)-| (Names: '|':BluePrintView:0x7fbeb1e7ac30 )>",
"<NSLayoutConstraint:0x7fbeb1e7e9b0 V:[UITableView:0x7fbeb2843000(480)]>",
"<NSLayoutConstraint:0x7fbeb1e81a20 '_UITemporaryLayoutHeight' V:[BluePrintView:0x7fbeb1e7ac30(0)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fbeb1e7e700 V:[UITableView:0x7fbeb2843000]-(0)-| (Names: '|':BluePrintView:0x7fbeb1e7ac30 )>
I solved these warnings by removing |
line from [tableView]
(by removing bottom constraint to superView), but then tableView does not get desire height.
Any idea how to get full tableView height with out any constraint warnings.
P.S. All views are created by code, no XIB no Storyboard layout. iOS 9.2
Upvotes: 0
Views: 1238
Reputation: 2303
I did not see any error in your constraints setup.
You may see this UITemporaryLayoutHeight constraint because you added the contentSize observer ([self.tableView addObserver:self forKeyPath:@"contentSize" options:0 context:NULL]
) too soon in your view life cycle, which triggers a [self.tableView layoutIfNeeded]
.
Try to add the observer in the viewDidLoad
, remove it in dealloc
of your View Controller ; Or in your viewWillAppear
, and remove it in the viewWillDisappear
for exemple.
Upvotes: 1