给定具有多行标签的集合视图单元格的宽度,如何获得首选的 AutoLayout 高度?

Posted

技术标签:

【中文标题】给定具有多行标签的集合视图单元格的宽度,如何获得首选的 AutoLayout 高度?【英文标题】:How to get preferred AutoLayout height given a width for a collection view cell with multiline labels? 【发布时间】:2018-07-16 22:06:03 【问题描述】:

我正在使用UICollectionView 在我的应用程序中构建一个具有自我调整大小的列表视图。让UICollectionViewFlowLayout 做垂直列表布局很痛苦,所以我正在编写自己的UICollectionViewLayout 子类来做。

我的单元格看起来很像常规的表格视图单元格 - 左侧是图像视图,中间垂直堆叠了几个标签,右侧是辅助视图。标签可以换行到几行并根据系统字体大小设置增大字体大小,这就是它们需要自行调整大小的原因。约束是明智的 - 左侧到图像视图,图像视图到标签,标签到附件,附件到右侧,标签到顶部和底部。

要通过preferredLayoutAttributesFittingAttributes 调整单元格大小,我需要在给定集合视图宽度的情况下获得所需的单元格高度。我希望为此使用systemLayoutSizeFittingSize:horizontalPriority:verticalPriority:,传递类似desiredWidth, crazyLargeHeightUILayoutPriorityRequired 用于水平优先级和1 用于垂直优先级的大小。但是我从systemLayoutFittingSize 得到的尺寸是不明智的。宽度是单元格中的某个先前宽度值(不一定与self.bounds.size.width 或传入的layoutAttributes'size.width 匹配),以及与该宽度一起使用的高度。我也尝试过传递一个小的高度而不是一个大的高度,但它仍然没有返回它实际需要的大小。

那么如何在给定宽度值的情况下获得单元格的首选高度?

示例代码:

-(UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes

  UICollectionViewLayoutAttributes *result = [super preferredLayoutAttributesFittingAttributes:layoutAttributes];
  CGSize exampleSize = CGSizeMake(layoutAttributes.size.width, 20);
  CGSize size = [self systemLayoutSizeFittingSize:exampleSize withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:1];
  result.size = size;
  return result;

【问题讨论】:

你需要你的selfself-sizing,因为它有足够的内部约束,所以当systemLayoutSizeFittingSize,内部约束为尺寸问题提供了一个解决方案。看看一个有效的例子对你有帮助吗? " 以为我可能误解了 systemLayoutSizeFittingSize。"好吧,看来您误解了它。但如果条件和调用正确,它做你希望做的事。 @matt 完全正确。这意味着我需要修补。 @matt and... 结果是,如果您向 self.contentView 询问 systemLayoutSizeFittingSize,它的效果非常好。发布答案以防其他人有一天也遇到同样的问题。 【参考方案1】:

事实证明,如果您询问单元格的内容视图而不是单元格本身的大小,它会起作用。而且您必须提供一个小于所需的样本高度。

-(UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes

  UICollectionViewLayoutAttributes *result = [super preferredLayoutAttributesFittingAttributes:layoutAttributes];
  CGSize exampleSize = CGSizeMake(layoutAttributes.size.width, 20); //magic number for example purposes...my cell will definitely be taller
  CGSize size = [self.contentView systemLayoutSizeFittingSize:exampleSize withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:1];
  result.size = size;
  return result;

我猜内容视图没有按我预期的方式固定到单元格的边界。如果内容视图由于某种原因被插入,这个确切的实现可能会失败。但解决这个问题的关键是,将单元格内容固定到单元格的内容视图并不意味着单元格本身会按照您的预期计算大小。

【讨论】:

以上是关于给定具有多行标签的集合视图单元格的宽度,如何获得首选的 AutoLayout 高度?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 AutoLayout 设置 UICollectionViewCell 的宽度

如何创建具有最大宽度的多行 UILabel?

如何在布局转换期间为集合视图单元格的边框宽度/颜色设置动画?

设置集合视图单元格的动态宽度时出现问题

网格布局android / kotlin中单元格的高度和宽度相同

对具有多行表格单元格的表格中的多行使用标签标记