iOS16下invalidateIntrinsicContentSize不触发Cell的intrinsicContentSize?
iOS 16 下 UICollectionViewCell 调用 invalidateIntrinsicContentSize() 不触发尺寸重算问题
问题表现
此前通过在UICollectionViewCell中调用invalidateIntrinsicContentSize()触发自定义UI动态尺寸计算的逻辑,在iOS 16 beta及以上版本设备上失效:调用方法后,子类重写的intrinsicContentSize属性不会被系统调用执行。
问题核心代码如下:
class DynamicCell: UICollectionViewCell { func invokeResize() { cell.subviews.forEach { $0.resize() } // iOS 16 起此处调用不会触发 intrinsicContentSize 执行 invalidateIntrinsicContentSize() } override var intrinsicContentSize: CGSize { return calculateDynamicCellSize() } }
该现象出现的节点和苹果新增UICollectionView.selfSizingInvalidation属性的版本重合,无法直接判定是系统实现引入的Bug,还是官方刻意调整的接口使用规则。
兼容适配方案
经实测,通过手动调用父类层级的invalidateIntrinsicContentSize()方法绕开UICollectionReusableView层的新实现,即可在iOS 16及以上版本正常触发尺寸重算,适配代码如下:
class RevisedDynamicCell: UICollectionViewCell { func invokeResize() { cell.subviews.forEach { $0.resize() } if #available(iOS 16.0, *) { // 直接调用UIView层的invalidateIntrinsicContentSize实现,可正常触发尺寸重算 invalidateUIViewIntrinsicContentSize() } else { invalidateIntrinsicContentSize() } } override var intrinsicContentSize: CGSize { return calculateDynamicCellSize() } } extension UICollectionReusableView { func invalidateUIViewIntrinsicContentSize() { super.invalidateIntrinsicContentSize() } }
适配说明:
- iOS 16中
UICollectionReusableView重写了invalidateIntrinsicContentSize()方法,默认对接新增的selfSizingInvalidation逻辑,不会直接触发intrinsicContentSize的查值流程- 穿透调用到UIView层的原方法实现,即可恢复iOS 16之前版本的触发逻辑
- 如果项目已经接入iOS 16新增的selfSizing失效机制,建议直接按照新API规范调整尺寸刷新逻辑,无需使用该兼容方案
内容的提问来源于stack exchange,提问作者mqz.kim
相关产品推荐
相关产品推荐

