Reputation: 7040
I'm trying to display content in a table cell using auto layout, programmatically. I'd like for the content to display as follows:
[title]
[image] [date]
[long string of text, spanning the width of the table, maximum of two lines]
My code looks like this:
-(NSArray *)constraints {
NSMutableArray * constraints = [[NSMutableArray alloc]init];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_titleLabel, _descriptionLabel, _dateLabel, _ratingBubbleView);
NSDictionary *metrics = @{@"padding":@(kPadding)};
NSString *const kVertical = @"V:|-(>=0,<=padding)-[_titleLabel]-(<=padding)-[_ratingBubbleView]-(<=padding)-[_descriptionLabel]-(>=0,<=padding)-|";
NSString *const kVertical2 = @"V:|-(>=0,<=padding)-[_titleLabel]-(<=padding)-[_dateLabel]-(<=padding)-[_descriptionLabel]-(>=0,<=padding)-|";
NSString *const kHorizontalDescriptionLabel = @"H:|-padding-[_descriptionLabel]-padding-|";
NSString *const kHorizontalTitleLabel = @"H:|-padding-[_titleLabel]";
NSString *const kHorizontalDateLabel = @"H:|-padding-[_ratingBubbleView]-padding-[_dateLabel]";
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kVertical options:0 metrics:metrics views:viewsDictionary]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kVertical2 options:0 metrics:metrics views:viewsDictionary]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kHorizontalDescriptionLabel options:0 metrics:metrics views:viewsDictionary]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kHorizontalTitleLabel options:0 metrics:metrics views:viewsDictionary]];
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kHorizontalDateLabel options:0 metrics:metrics views:viewsDictionary]];
return constraints;
}
This is the result:
Upvotes: 0
Views: 318
Reputation: 77661
OK, I'm not going to try a fix your code. I'm just going to create constraints that I would use to achieve your layout. I'll put the thought process in comments.
First get a nice vertical layout going...
// I'm just using standard padding to make it easier to read.
// Also, I'd avoid the variable padding stuff. Just set it to a fixed value.
// i.e. ==padding not (>=0, <=padding). That's confusing to read and ambiguous.
@"V:|-[titleLabel]-[ratingBubbleView]-[descriptionLabel]-|"
Then go through layer by layer adding horizontal constraints...
// constraint the trailing edge too. You never know if you'll get a stupidly
// long title. You want to stop it colliding with the end of the screen.
// use >= here. The label will try to take it's intrinsic content size
// i.e. the smallest size to fit the text. Until it can't and then it will
// break it's content size to keep your >= constraint.
@"|-[titleLabel]->=20-|"
// when adding this you need the option "NSLayoutFormatAlignAllBottom".
@"|-[ratingBubbleView]-[dateLabel]->=20-|"
@"|-[descriptionLabel]-|"
Try not to "over constrain" your view. In your code you are constraining the same views with multiple constraints (like descriptionLabel to the bottom of the superview).
Once they're defined they don't need to be defined again.
Again, with the padding. Just use padding
rather than >=padding
. Does >=20 mean 20, 21.5, or 320? The inequality is ambiguous when laying out.
Also, In my constraints I have used the layout option to constrain the vertical axis of the date label to the rating view. i.e. "Stay in line vertically with the rating view". Instead of constraining against the title label and stuff... This means I only need to define the position of that line of UI once.
Upvotes: 1