iOS 7/8 UITableView单元格:两个具有动态高度的UILabel,具有可变行高的自动布局
因此,当我只有一个标签根据字符串的长度更改高度时,我可以使用自动布局设置动态高度大小调整。 我的问题是,如果我添加另一个UILabel也应该这样做,那么事情就不会成功 我将内容拥抱优先级和压缩阻力都设置为1000,因为这两个==我收到了歧义警告 如果我将第二个UILabel的内容拥抱(垂直)设置为999或250,则效果很好,但前提是第二个标签有两行或更多行。如果第二个标签为空或只有一行,则行的高度IndexPath systemLayoutSizeFittingSize:UILayoutFittingCompressedSize高度将返回较大的值,并且单元格具有较大的空格 我还使用了固有的大小:默认值或占位符(带有两个高度和宽度),但它也没有帮助iOS 7/8 UITableView单元格:两个具有动态高度的UILabel,具有可变行高的自动布局,ios,uitableview,uilabel,autolayout,Ios,Uitableview,Uilabel,Autolayout,因此,当我只有一个标签根据字符串的长度更改高度时,我可以使用自动布局设置动态高度大小调整。 我的问题是,如果我添加另一个UILabel也应该这样做,那么事情就不会成功 我将内容拥抱优先级和压缩阻力都设置为1000,因为这两个==我收到了歧义警告 如果我将第二个UILabel的内容拥抱(垂直)设置为999或250,则效果很好,但前提是第二个标签有两行或更多行。如果第二个标签为空或只有一行,则行的高度IndexPath systemLayoutSizeFittingSize:UILayoutFitt
谁有什么建议可以做吗?我终于成功了。我的解决方案是将首选宽度显式设置为当前帧宽度。 因此,基本上检查尺寸检查器中标签>首选宽度中的显式复选标记 参考:
下载示例代码并查看故事板设置 对于我来说,将内容拥抱优先级和内容压缩阻力优先级设置为较低的一个元素,效果与预期一样。对于我来说,这需要综合考虑多种因素
- 除了正确设置内容拥抱和阻力之外
- 我必须创建UILabel的子类来处理标签的preferredMaxLayoutWidth
- 并纠正intrinsicContentSize中的错误
@implementation LabelDynamicHeight
- (void)layoutSubviews
{
[super layoutSubviews];
self.preferredMaxLayoutWidth = self.frame.size.width;
[super layoutSubviews];
}
- (void)setBounds:(CGRect)bounds
{
[super setBounds:bounds];
if (self.numberOfLines == 0)
{
CGFloat boundsWidth = CGRectGetWidth(bounds);
if (self.preferredMaxLayoutWidth != boundsWidth)
{
self.preferredMaxLayoutWidth = boundsWidth;
[self setNeedsUpdateConstraints];
}
}
}
- (CGSize)intrinsicContentSize
{
CGSize size = [super intrinsicContentSize];
if (self.numberOfLines == 0)
{
// There's a bug where intrinsic content size may be 1 point too short
size.height += 1;
}
return size;
}
@end
- (CGFloat)tableView:( UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = ...;
CGFloat height = cell.frame.size.height;
if (cell.dynamicHeight)
{
// https://stackoverflow.com/a/26351692/1840269
[cell layoutIfNeeded];
height = cell.frame.size.height;
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
if (size.height > height)
height = size.height;
}
return height;
}
除此之外,在获取tableView中的高度之前,需要在单元格上调用layoutifn。heightForRowAtIndexPath:
在contentView上使用systemLayoutSizeFittingSize:
方法之前,必须准备好约束。看起来像这样:
@implementation LabelDynamicHeight
- (void)layoutSubviews
{
[super layoutSubviews];
self.preferredMaxLayoutWidth = self.frame.size.width;
[super layoutSubviews];
}
- (void)setBounds:(CGRect)bounds
{
[super setBounds:bounds];
if (self.numberOfLines == 0)
{
CGFloat boundsWidth = CGRectGetWidth(bounds);
if (self.preferredMaxLayoutWidth != boundsWidth)
{
self.preferredMaxLayoutWidth = boundsWidth;
[self setNeedsUpdateConstraints];
}
}
}
- (CGSize)intrinsicContentSize
{
CGSize size = [super intrinsicContentSize];
if (self.numberOfLines == 0)
{
// There's a bug where intrinsic content size may be 1 point too short
size.height += 1;
}
return size;
}
@end
- (CGFloat)tableView:( UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = ...;
CGFloat height = cell.frame.size.height;
if (cell.dynamicHeight)
{
// https://stackoverflow.com/a/26351692/1840269
[cell layoutIfNeeded];
height = cell.frame.size.height;
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
if (size.height > height)
height = size.height;
}
return height;
}
参考资料:
- 适合内容拥抱和抵抗:
- preferredMaxLayoutWidth操作的说明:
- 具有intrinsicContentSize修复的UILabel子类的灵感: