I programmatically created layout constraints to arrange UI components in a table cell.
Here are the constraints I'm implementing:
nameUIView
(done)valueUIView
(done)nameUIView
and valueUIView
part should be equal (done)nameUIView
and valueUIView
should be 100% of the available space (done)nameUIView
contains a nameUILabel
(done)nameUILabel
should use line wrapping by word (need advice)nameUILabel
grows too large (need advice)How could I achieve line wrapping and height expansion for that layout programmatically?
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
NSString *reuseID = reuseIdentifier;
// The view containing the label (left, red)
UIView *nameUIView = [[UIView alloc] init];
self.nameUIView = attributeNameView;
[self.nameUIView setBackgroundColor:[UIColor redColor]];
[self.nameUIView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.contentView addSubview:self.nameUIView];
// The label (green)
UILabel *nameUILabel = [[UILabel alloc] init];
self.nameUILabel = nameUILabel;
[self.nameUILabel setTextColor:[UIColor blackColor]];
[self.nameUILabel setBackgroundColor:[UIColor greenColor]];
[self.nameUILabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.nameUILabel setLineBreakMode:NSLineBreakByWordWrapping];
[self.nameUIView addSubview:self.nameUILabel];
// The view containing the value (right, blue)
UIView *valueUIView = [[UIView alloc] init];
self.valueUIView = valueUIView;
[self.valueUIView setBackgroundColor:[UIColor blueColor]];
[self.valueUIView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.contentView addSubview:self.valueUIView];
NSDictionary *views = NSDictionaryOfVariableBindings(nameUIView, nameUILabel, valueUIView);
NSArray *constraints;
// The constraint to align the views horizonzally (1:1) sizing
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[nameUIView][valueUIView(==nameUIView)]|"
options: 0
metrics:nil
views:views];
[self.contentView addConstraints:constraints];
// 100% height for name view
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameUIView]|"
options: 0
metrics:nil
views:views];
[self.contentView addConstraints:constraints];
NSLayoutConstraint *constraint;
// Center name label horizontally
constraint = [NSLayoutConstraint constraintWithItem:nameUILabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:nameUIView
attribute:NSLayoutAttributeCenterX
multiplier:1.f constant:0.f];// Not possible via VFL
[self.contentView addConstraint:constraint];
// Center name label vertically
constraint = [NSLayoutConstraint constraintWithItem:nameUILabel
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:nameUIView
attribute:NSLayoutAttributeCenterY
multiplier:1.f constant:0.f];// Not possible via VFL
[self.contentView addConstraint:constraint];
// 100% height for value view
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[valueUIView]|"
options: 0
metrics:nil
views:views];
[self.contentView addConstraints:constraints];
}
return self;
}
Adding this additional constraint (set width of label to parent view) did enable word wrapping:
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[attributeNameLabel(==attributeNameView)]|"
options: 0
metrics:nil
views:views];
[self.contentView addConstraints:constraints];
Finally, I had to center the text:
[self.attributeNameLabel setTextAlignment:NSTextAlignmentCenter];
It is also needed to set these properties for UITableView
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight =
Set the height of the wrapping superview tame as the label it contains
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameUIView(==nameUILabel)]|"
options: 0
metrics:nil
views:views];
[self.contentView addConstraints:constraints];
Minimum height constraint (optional)
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[nameUIView(>=50)]|"
options: 0
metrics:nil
views:views];
[self.contentView addConstraints:constraints];