当内容太长时,具有 .estimated 宽度的组合布局项目会导致应用程序崩溃

问题描述

我正在探索使用组合布局的奇妙世界,我发现了一个需要帮助的小情况。下面是一个简单的应用程序,它使用带有 CL 的 CollectionView 来显示使用 T 圆角单元格的随机字符串。项目的宽度为 UIListContentConfiguration,因此我可以根据单元格的内容获得自行调整大小的单元格(宽度)。这非常有效,直到我将字符数从 50 增加到 100。(目前在 iPad Pro 9.7 上运行)。似乎 100 个字符超过了 CollectionView 的宽度,这让我的应用开始使用大量内存,直到由于同样的原因崩溃。

如何复制: 将要显示的字符数更改为更高的数字。前任。 .estimated(30)

return (1...100).compactMap { $0; return self.randomString(length: .random(in: 1..<150))}

解决方法

这似乎是 Apple 组合布局中的一个错误。正如您在问题中所展示的那样,很容易重现。当单元格的宽度超过集合视图的宽度时,应用程序会挂起,因为它在主线程上做了过多的工作。此时(当应用程序冻结或无响应时)您可以通过 XCode 停止执行并看到 Apple 的内部 API 在不断分配内存的同时进入某种无限循环。因此最终崩溃...

不幸的是,解决方案/变通方法是将单元格的宽度限制在合理的范围内,这样它们就不会超过集合视图自身的宽度。也许使用自动布局规则,或者使用您从 UICollectionViewCompositionalLayout 获得的布局信息,例如:

    func createCompositionalLayout() -> UICollectionViewCompositionalLayout {
        return UICollectionViewCompositionalLayout { (section,layoutEnvironment) -> NSCollectionLayoutSection? in
            
            // use availableWidth variable to determine the max size for your cells
            let availableWidth: CGFloat = layoutEnvironment.container.effectiveContentSize.width
            ...
            ... do some additional layout work
            ...
        }
    }