Dee*_*hat 11 uikit ios swift5 ios15
我有一个自动调整大小的集合视图,当我调用 super.layoutSubviews 时,我的应用程序崩溃,因为集合视图进入递归更新循环。这在 iOS 14 及更低版本中运行良好。但从 iOS 15 开始就观察到了这一点。
class DynamicCollectionView: UICollectionView {
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
}
}
override func layoutSubviews() {
super.layoutSubviews()
if bounds.size != intrinsicContentSize {
invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
return contentSize
}
override func reloadData() {
super.reloadData()
invalidateIntrinsicContentSize()
layoutIfNeeded()
}
Run Code Online (Sandbox Code Playgroud)
}
崩溃 说:
由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“UICollectionView(<KPFlagship.SelfSizingCollectionView 0x7f896b260e00>)卡在其更新/布局循环中。发生这种情况的原因有很多,包括自调整大小的视图,其首选属性未返回一致的大小。要调试此问题,请检查控制台应用程序中“UICollectionViewRecursion”类别中的日志。
在我们的例子中(垂直流动布局collectioview,垂直自调整大小的单元格),问题是我有一些单元格没有实现重写preferredLayoutAttributesFitting:
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
let targetSize = CGSize(width: layoutAttributes.frame.width, height: 0)
layoutAttributes.frame.size = contentView
.systemLayoutSizeFitting(targetSize,
withHorizontalFittingPriority: .required,
verticalFittingPriority: .fittingSizeLevel)
return layoutAttributes
}
Run Code Online (Sandbox Code Playgroud)
这是类似于我们的流程布局:
final class VerticalFlowLayout: UICollectionViewFlowLayout {
override init() {
super.init()
scrollDirection = .vertical
estimatedItemSize = UICollectionViewFlowLayout.automaticSize
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let layoutAttributesObjects = super.layoutAttributesForElements(in: rect)
layoutAttributesObjects?.enumerated()
.forEach { (index, layoutAttributes) in
if layoutAttributes.representedElementCategory == .cell {
guard let newFrame = layoutAttributesForItem(at: layoutAttributes.indexPath)?.frame else {
return
}
layoutAttributes.frame = newFrame
}
}
return layoutAttributesObjects
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
guard let collectionView = collectionView else {
return nil
}
guard let layoutAttributes = super.layoutAttributesForItem(at: indexPath) else {
return nil
}
layoutAttributes.frame.origin.x = sectionInset.left
layoutAttributes.frame.size.width = collectionView.safeAreaLayoutGuide.layoutFrame.width - sectionInset.left - sectionInset.right
return layoutAttributes
}
}
Run Code Online (Sandbox Code Playgroud)
因此,在ios 15之前的 ios 版本中,collectionview 和 cells 没有问题。在为ios 15+构建相同的代码后,开始陷入更新/布局循环。
因此,如果您遇到类似的问题,请尝试找出您正在使用哪种类型的自定义布局,并尝试根据preferredLayoutAttributesFitting返回。
PS如果你(读这篇文章的人)有任何见解为什么它在ios15之前有效而在ios15之后不起作用,ios15中实际上发生了什么变化导致了这样的问题,请与我们分享,ty :)
| 归档时间: |
|
| 查看次数: |
6623 次 |
| 最近记录: |