我正在使用 Masonry pod 来控制我对 tableView 中 UI 元素的约束,并且我的视图扩展了 UITableViewCell。每个单元格有三个 UI 元素,显示热门邮轮港口的评级和评论。根据端口是否已评级,移除和更换其中一个元素。
大约在一周前之前,用于审查的 UILabel 显示时没有任何额外的填充,但现在它显示在 UILabel 的顶部和底部似乎有 2 行额外的填充。
以下是相关代码:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.rating = 0;
//solves autolayout error http://stackoverflow.com/questions/19132908/auto-layout-constraints-issue-on-ios7-in-
// self.contentView.bounds = CGRectMake(0, 0, 99999, 99999);
// description label
self.descriptionLabel = [[UILabel alloc] init];
[self.descriptionLabel setPreferredMaxLayoutWidth:self.contentView.bounds.size.width];
[self.descriptionLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.descriptionLabel setFont:[UIFont fontWithName:[StringFactory defaultFontType] size:14.0f]];
[self.descriptionLabel setTextColor:[ColorFactory CC333]];
[self.descriptionLabel setNumberOfLines:0];
[self.descriptionLabel sizeToFit];
// Without this, it can happen that the last line of the text to be displayed can be cut, although
// all the proper constraints seem to be set correctly.
[self.descriptionLabel setAdjustsFontSizeToFitWidth:NO];
[self.descriptionLabel setBackgroundColor:[ColorFactory CCOrange]];
[self.contentView addSubview:self.descriptionLabel];
// create date label
self.dateLabel = [[UILabel alloc] init];
[self.dateLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.dateLabel setFont:[UIFont fontWithName:[StringFactory defaultFontType] size:14.0f]];
[self.dateLabel setTextColor:[ColorFactory CC333]];
[self.contentView addSubview:self.dateLabel];
//create ratingView
self.ratingView = [[UIImageView alloc] init];
[self.ratingView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.contentView addSubview:self.ratingView];
// create ratingLabel
self.ratingLabel = [[UILabel alloc] init];
[self.ratingLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.ratingLabel setFont:[UIFont fontWithName:[StringFactory defaultBoldFontType] size:14.0f]];
[self.ratingLabel setTextColor:[ColorFactory CC333]];
[self.contentView addSubview:self.ratingLabel];
self.contentView.backgroundColor = [UIColor whiteColor];
// add KVO to update cell
[self addObserver:self forKeyPath:@"portReview" options:NSKeyValueObservingOptionNew context:nil];
//Add constraints
[self setLayout];
}
return self;
}
- (void)dealloc {
[self removeObserver:self forKeyPath:@"portReview" context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"portReview"]) {
[self configureCell];
}
}
- (void)configureCell {
self.descriptionLabel.text = self.portReview.review;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone: [NSTimeZone timeZoneWithAbbreviation:@"EST"]];
[dateFormatter setDateFormat:[StringFactory shortDateFormat]];
NSMutableString *authorString = [NSMutableString stringWithString:@""];
if (self.portReview.author != nil)
{
authorString = [NSMutableString stringWithFormat:@"(%@)", self.portReview.author];
}
self.dateLabel.text = [NSString stringWithFormat:@"%@ %@", [dateFormatter stringFromDate:self.portReview.createdAt], authorString];
// Rating can never exceed 5 bubbles. In case the rating provided is greater than 5, round down to 5.
CGFloat roundedRating = MIN(round([self.portReview.rating floatValue] * 2) / 2, 5.0f);
roundedRating = MAX(0, roundedRating);
self.rating = roundedRating;
if (self.rating > 0)
{
[self.contentView addSubview:self.ratingView];
[self.ratingView setImage:[UIImage imageNamed:[NSString stringWithFormat:@"cc_bubbles_%.1f.png", roundedRating]]];
if ([self.ratingLabel isDescendantOfView:self.contentView])
{
[self.ratingLabel removeFromSuperview];
}
if (self.ratingLabel.constraints)
{
[self.ratingLabel removeConstraints:self.ratingLabel.constraints];
}
}
else
{
[self.contentView addSubview:self.ratingLabel];
[self.ratingLabel setText:@"Not Rated"];
if ([self.ratingView isDescendantOfView:self.contentView])
{
[self.ratingView removeFromSuperview];
}
if (self.ratingView.constraints)
{
[self.ratingView removeConstraints:self.ratingView.constraints];
}
}
[self setLayout];
}
-(void)setLayout
{
typeof (self) __weak weakSelf = self;
// rating
if (self.rating > 0)
{
[self.ratingView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(weakSelf.contentView.mas_top).with.offset(kPadding);
make.left.equalTo(weakSelf.contentView.mas_left).with.offset(kPadding);
make.height.equalTo(@20);
make.width.equalTo(@100);
}];
}
else
{
[self.ratingLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(weakSelf.contentView.mas_top).with.offset(kPadding);
make.left.equalTo(weakSelf.contentView.mas_left).with.offset(kPadding);
make.height.equalTo(@20);
make.width.equalTo(@100);
}];
}
// date label
[self.dateLabel mas_makeConstraints:^(MASConstraintMaker *make) {
if (weakSelf.rating > 0)
{
make.top.equalTo(weakSelf.ratingView.mas_bottom).with.offset(kPadding);
}
else
{
make.top.equalTo(weakSelf.ratingLabel.mas_bottom).with.offset(kPadding);
}
make.left.equalTo(weakSelf.contentView.mas_left).with.offset(kPadding);
make.right.equalTo(weakSelf.contentView.mas_right).with.offset(-kPadding);
}];
// description
[self.descriptionLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(weakSelf.dateLabel.mas_bottom).with.offset(kPadding);
make.left.equalTo(weakSelf.contentView.mas_left).with.offset(kPadding);
make.right.equalTo(weakSelf.contentView.mas_right).with.offset(-kPadding);
make.bottom.equalTo(weakSelf.contentView.mas_bottom).with.offset(-kPadding);
}];
}
输出(背景为橙色以突出填充):
为什么自动布局会添加此填充,我该如何摆脱它?它也出现在应用程序的其他区域,所以我想了解它为什么会发生,以便我可以修复不需要的布局。
编辑:
每一行的高度计算tableView:heightForRowAtIndexPath
如下:
PortReviewTableViewCell* cell = self.autoLayoutCell;
cell.portReview = self.portReviews[indexPath.row];
// Since we have multi-line labels, do an initial layout pass and then set the preferredMaxLayoutWidth
// based on their width so they will wrap text and take on the correct height
[cell.contentView setNeedsLayout];
[cell.contentView layoutIfNeeded];
cell.descriptionLabel.preferredMaxLayoutWidth = CGRectGetWidth(cell.descriptionLabel.frame);
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
return height;