systemLayoutSizeFitting 忽略布局约束并使用图像视图固有大小

Posted

技术标签:

【中文标题】systemLayoutSizeFitting 忽略布局约束并使用图像视图固有大小【英文标题】:systemLayoutSizeFitting ignoring layout constraints and using image view intrinsic size 【发布时间】:2017-06-28 11:45:21 【问题描述】:

我正在为UICollectionView 使用自定义布局。我的单元格应该有固定的宽度和灵活的高度。

单元格由UImageViewUIStackView 组成。 UIImageView 的约束如下:

image.top = cell.top
image.width = cell.width
image.height = image.width * 1.33
image.centerX = cell.centerX
image.bottom = stackView.top 

堆栈视图类似,并且确实绑定到单元格的底部。

当系统调用preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes

我正在执行一些计算以获取单元格的高度。

let preferredAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)


let size = CGSize(width: layoutAttributes.frame.width,
                  height: UILayoutFittingCompressedSize.height)

let preferredSize = systemLayoutSizeFitting(size,
                                            withHorizontalFittingPriority: .defaultHigh,
                                            verticalFittingPriority: .fittingSizeLevel)

事实证明,preferredSize 是使用 imageView 固有大小而不是遵守约束来计算的。因此,对于 850x850 的图像(以及宽度为 160 点的单元格),我得到的高度比我预期的要高得多,因此单元格的底部空间很大。

我设法用我觉得这是一个 hack 的东西解决了这个问题。

我创建了对图像宽度约束的引用,当我使用从 layoutAttributes 获得的固定值调用此方法并调用 setNeedsLayout() 和 layoutIfNeeded() 时对其进行更新,这样就可以了。但我真的不喜欢我必须再次强制布局并自己更新宽度,更不用说我失去了性能。

如何以更好的方式做到这一点?

非常感谢。

【问题讨论】:

你可以尝试覆盖 viewDidLayoutSubviews 【参考方案1】:

你有纵横比限制吗? systemLayoutSizeFitting 在有纵横比约束时无法正常工作。

首先,尝试在图像上设置高度约束而不是纵横比,如果可行,请在代码中设置高度约束常量 = image.width * 1.33

【讨论】:

这就是我修复它的方式,但我不喜欢我必须自己做它并调用 layoutIfNeeded() 因为我也有性能问题,想避免它。 您能否提供更多有关 systemLayoutSizeFitting 无法在纵横比下正常工作的详细信息?你有和参考吗? @NunoGonçalves 实际上,这是一个常见的问题。如果不设置高度约束,systemLayoutSize 使用intrinsicContentSize 计算高度。这是此问题的另一种解决方案***.com/questions/25664716/…

以上是关于systemLayoutSizeFitting 忽略布局约束并使用图像视图固有大小的主要内容,如果未能解决你的问题,请参考以下文章

Python解析CSV忽略带双引号的逗号

SQL:如何将 first_value 忽略为聚合?

从 csv 文件批量插入 - 忽略有错误的行 - SQL Server

EF部分字段更新,忽略为null字段

如何在 csv 文件中忽略带引号的换行符以创建 Hive 外部表?

Protobuf-net / NetCore2:反序列化忽略带注释的私有字段