You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS15及以上Self sizing Collection View调用layoutSubviews递归崩溃

问题根因

该问题是iOS 15对UICollectionView布局逻辑调整后触发的:

  • iOS 15新增了UICollectionView布局递归检测机制,当检测到布局更新进入无限循环时会直接抛出异常,iOS 14及更低版本没有该检测逻辑,所以不会崩溃。
  • 原有代码存在多处冗余的布局更新触发逻辑,刚好满足递归循环的条件:
    1. 重写的layoutSubviews中调用invalidateIntrinsicContentSize后,会触发系统重新计算视图尺寸,进而再次调用layoutSubviews,形成第一重循环。
    2. contentSize的didSet钩子会触发invalidateIntrinsicContentSize,而intrinsicContentSize直接返回contentSize,二者形成第二重联动循环。
    3. reloadData中强制调用layoutIfNeeded会提前触发布局计算,和前两个逻辑叠加后直接触发递归检测。

修复方案

删除冗余的触发逻辑,仅保留必要的自适应尺寸代码即可,修改后代码如下:

class DynamicCollectionView: UICollectionView {
    override var contentSize: CGSize {
        didSet {
            // 仅当尺寸真实变化时才触发更新,避免无效调用
            if contentSize != intrinsicContentSize {
                invalidateIntrinsicContentSize()
            }
        }
    }

    override var intrinsicContentSize: CGSize {
        return contentSize
    }

    override func reloadData() {
        super.reloadData()
        invalidateIntrinsicContentSize()
    }
}

额外注意事项:

  • 要保证该CollectionView的自动布局约束没有添加固定宽高限制,才可以正常跟随contentSize自适应尺寸。
  • 如果需要仅自适应高度/宽度某一个维度,可以在intrinsicContentSize的实现中固定另一个维度的返回值即可。

内容的提问来源于stack exchange,提问作者Deepa Bhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 12:24:04