How to properly constrain UITableView using Auto Layout
-
21-12-2019 - |
Frage
I want to place a UITableView such that it takes up the entirety of one of my view controller's subviews. Here's the view hierarchy, where self
is my UIViewController subclass:
[self.view] -> [self.rootView] -> [self.tableView]
I know that I need to set setTranslatesAutoresizingMaskIntoConstraints
to NO
for any view whose subviews I want to lay out with Auto Layout, so here's my viewDidLoad
.
[super viewDidLoad];
self.rootView = [[UIView alloc]initWithFrame:CGRectMake(0.0, 0.0, 320.0, 568.0)];
[self.rootView setTranslatesAutoresizingMaskIntoConstraints:NO];
So far so good. Now I want to add a UITableView.
self.tableView = [[UITableView alloc]init]; // same thing with initWithFrame:CGRectZero
[self.rootView addSubview:self.tableView];
No problem so far, but I can't see the table view (because it doesn't have a frame). Let's add some constraints:
[self.rootView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-0-[table]-0-|" options:0 metrics:nil views:@{@"table": self.tableView}]];
[self.rootView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[table]-0-|" options:0 metrics:nil views:@{@"table": self.tableView}]];
Everything breaks. self.rootView.backgroundColor
is green and the cells are blue and full of text, but there's nothing on the screen but grey, maybe indicating that self.view
is no longer in the view hierarchy? I've done a bunch of googling but can't find a real solution anywhere. I've also tried adding all the constraints one at a time the other way and the same thing happens. Does anyone have any ideas?
Lösung
I believe you should be calling setTranslatesAutoresizingMaskIntoConstraints:NO
on your UITableView
instead of on self.rootView
. But as rdelmar commented, first make sure your table view is not what you are seeing with the grey background since it will fill the screen and cover the other views.
And another note, I believeself.rootView = [[UIViewController alloc]initWithFrame...]
above actually should be [[UIView alloc] initWithFrame...]
since controllers don't have frames but maybe it's just incorrect above as this would cause an error when trying to run.