在iOS 10之前,我有一个自我调整表视图,它只包含一个UICollectionView,其中包含使用标准UICollectionViewFlowLayout的自调整单元格。使用自动布局调整集合视图单元格的大小。为了使表格单元格能够正确调整大小,我必须找到集合视图的内容大小,并在表格单元格的systemLayoutSizeFittingSize中使用它:withHorizontalFittingPriority:verticalFittingPriority:。
我还发现对collectionView.collectionViewLayout.collectionViewContentSize的调用使用了estimatedItemSize而不是正确大小的单元格大小,除非我调用了collectionView layoutIfNeeded。这导致systemLayoutSizeFittingSize:
- (CGSize) systemLayoutSizeFittingSize:(CGSize)targetSize withHorizontalFittingPriority:(UILayoutPriority)horizontalFittingPriority verticalFittingPriority:(UILayoutPriority)verticalFittingPriority
{
self.collectionView.frame = CGRectMake(0, 0, targetSize.width, FLT_MAX);
[self.collectionView layoutIfNeeded];
CGSize collectionViewContentSize = self.collectionView.collectionViewLayout.collectionViewContentSize;
CGFloat verticalPadding = fabs(self.collectionViewTopPaddingConstraint.constant) + fabs(self.collectionViewBottomPaddingConstraint.constant);
CGSize cellSize = CGSizeMake(collectionViewContentSize.width, collectionViewContentSize.height + verticalPadding);
return cellSize;
}
现在调用layoutIfNeeded会导致*** Assertion failure in -[_UIFlowLayoutSection computeLayoutInRect:forSection:invalidating:invalidationContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3599.6/UIFlowLayoutSupport.m:823
我是否通过在systemLayoutSizeFittingSize中调用layoutIfNeeded来违反某些道德规则?在使用自定义单元格时,是否有更好的方法来计算集合视图的内容大小?我宁愿不必从自动布局转到在代码中进行这些大小计算,但这肯定是最糟糕的选择。
答案 0 :(得分:16)
这是iOS10中仅有iPhone Plus设备的一些奇怪错误。我遇到了同样的问题,我的解决办法就是这样打layoutIfNeeded
:
func numberOfSections(in collectionView: UICollectionView) -> Int {
collectionView.layoutIfNeeded() // Patch: only to solve UIKit crash on Plus models
return 1
}
在不同的UICollectionViewDataSources方法中执行相同的操作也可以正常工作
答案 1 :(得分:1)
在iOS 10上开发我的应用程序时遇到同样的问题。删除第一行解决了我的问题。
self.collectionView.frame = CGRectMake(0, 0, targetSize.width, FLT_MAX); //Remove this
希望这有帮助!
答案 2 :(得分:1)
就我而言,在布局之前调用invalidateLayout
是此问题的解决方法。
在UIViewController
子类中:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
collectionView.collectionViewLayout.invalidateLayout()
}
或在UIView
子类中:
override func layoutSubviews() {
super.layoutSubviews()
collectionView.collectionViewLayout.invalidateLayout()
}
答案 3 :(得分:0)
我在iOS 10上开发我的应用时遇到同样的问题,并在UICollectionViewDataSource
上将awakeFromNib
设置为自己,如下所示:
override func awakeFromNib() {
super.awakeFromNib()
let layout = UICollectionViewFlowLayout()
// set your layout
collectionViewLayout = layout
// set dataSource equal to self in here cause a crash
dataSource = self
}
然后我将UICollectionViewDataSource
设置代码移到layoutSubviews
,问题解决了,就像这样:
override func layoutSubviews() {
super.layoutSubviews()
dataSource = self
}
override func awakeFromNib() {
super.awakeFromNib()
let layout = UICollectionViewFlowLayout()
// set your layout
collectionViewLayout = layout
// set dataSource equal to self in here cause a crash
dataSource = self
}
希望这有帮助!