多行 UILabel 有时会完全显示,有时会被切断
Posted
技术标签:
【中文标题】多行 UILabel 有时会完全显示,有时会被切断【英文标题】:Multiline UILabel sometimes displays fully, sometimes cuts off 【发布时间】:2015-05-13 16:36:45 【问题描述】:自从 ios 8 发布以来,我在评论显示视图中遇到了一个奇怪的问题,我的长多行标题并不总是在屏幕上显示完整标题。让这个问题更令人沮丧的是,显示不一致,有时会显示完整的标题,有时会像这样将其截断:
在我的 ViewController 中,cellForRowAtIndexPath
方法如下所示:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// 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
[self.cell.contentView setNeedsLayout];
[self.cell.contentView layoutIfNeeded];
[self.cell.titleLabel setPreferredMaxLayoutWidth:CGRectGetWidth(self.cell.contentView.frame)];
[self.cell.titleLabel sizeToFit];
[self.cell.descriptionLabel setPreferredMaxLayoutWidth:CGRectGetWidth(self.cell.contentView.frame)];
[self.cell.descriptionLabel sizeToFit];
return self.cell;
我的视图代码中init
的相关部分如下所示:
// title label
self.titleLabel = [[UILabel alloc] init];
[self.titleLabel setFont:[UIFont fontWithName:[StringFactory defaultFontType] size:kTitleFontSize]];
// if (self.review.title)
//
// [self.titleLabel setText:[NSString stringWithFormat:@"\"%@\"", self.review.title]];
//
// else
//
// [self.titleLabel setText:@""];
//
[self.titleLabel setText:@"\"This title should be too long to fit on one line. If it isn't, we have bigger problems.\""];
[self.titleLabel setTextColor:[ColorFactory CC333]];
[self.titleLabel setAdjustsFontSizeToFitWidth:NO];
[self.titleLabel setNumberOfLines:0];
[self.titleLabel sizeToFit];
[self.titleLabel setLineBreakMode:NSLineBreakByWordWrapping];
[self.titleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.titleLabel setBackgroundColor: [ColorFactory CCOrange]];
[self.contentView addSubview:self.titleLabel];
这里是约束设置(使用 Masonry):
typeof (self) __weak weakSelf = self;
// title
[self.titleLabel 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.right.equalTo(weakSelf.contentView.mas_right).with.offset(-kPadding);
];
[self.ratingBubbles mas_makeConstraints:^(MASConstraintMaker *make)
make.top.equalTo(weakSelf.titleLabel.mas_bottom).with.offset(5);
make.left.equalTo(weakSelf.contentView.mas_left).with.offset(kPadding);
make.height.equalTo(weakSelf.bubbleHeight);
make.width.equalTo(weakSelf.bubbleWidth);
];
[self.dateLabel mas_makeConstraints:^(MASConstraintMaker *make)
make.top.equalTo(weakSelf.titleLabel.mas_bottom).with.offset(5);
make.left.equalTo(weakSelf.ratingBubbles.mas_right).with.offset(kPadding);
make.right.equalTo(weakSelf.contentView.mas_right).with.offset(-kPadding);
];
// description
[self.descriptionLabel mas_makeConstraints:^(MASConstraintMaker *make)
make.top.equalTo(weakSelf.ratingBubbles.mas_bottom).with.offset(5);
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);
];
在过去两个月左右的时间里,我一直在尝试解决这个问题,断断续续,但到目前为止还没有任何运气。如果有人遇到过类似的问题,请发表您的经历。
【问题讨论】:
您是否有理由不使用新的自调整单元格 api? @rdelmar 我不熟悉它。一般来说,iOS 相当新。有链接吗? 【参考方案1】:尝试使用自调整单元格 api。只要您的单元格正确设置了约束,您只需在viewDidLoad
中添加几行,
- (void)viewDidLoad
[super viewDidLoad];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 50;
-(void)viewDidAppear:(BOOL)animated
[super viewDidAppear:animated];
[self.tableView reloadData]; // this may or may not be necessary I found that cells didn't size correctly until scrolled or rotated without this line in iOS 8.3
您的约束需要从单元格顶部到任何视图到底部是连续的。你不需要你目前在cellForRowAtIndexPath
中的任何代码;除了使单元格出列之外,您应该在那里做的唯一一件事就是设置标签的文本。在单元格类中,您不需要sizeToFit
,也不应该在那里设置文本。
【讨论】:
self-sizing cell API 是原生 Objective-c 库,还是需要安装可可豆荚? @Matt,它是原生的。有一个关于它的 WWDC 视频,我想是从 2014 年开始的。 给你的问题。什么会首先导致这种行为?帖子中的图像来自运行相同模拟的完全相同的代码。我点击评论,显示它,点击返回,然后点击评论以再次显示它。同样的动作,不同的结果。 @Matt,当您在视图之间来回移动时会发生一些布局操作,因此当您这样做时必须更新一些内容。 关于我应该在哪里调试的任何建议?loadView
? viewDidLoad
? viewDidAppear
?【参考方案2】:
是的,如 rdelmar 所述,自定尺寸单元可以帮助您解决此问题。需要注意的一个关键点是 uilabel 应正确设置自动布局约束,并且行数应设置为 0。
【讨论】:
以上是关于多行 UILabel 有时会完全显示,有时会被切断的主要内容,如果未能解决你的问题,请参考以下文章
当页面自动刷新但在谷歌浏览器中没有时,语音在 Firefox 中被切断
Streamwriter 有时会在一行中间切断我的最后几行?