我正在实现水平的自定义UICollectionViewFlowLayout,第一个/最后一个单元格应该位于视图的中间,并且具有自定义大小的单元格。
问题是,正确的sectionInset大于我的预期-未知的间隙添加到正确的sectionInset。
我实现了以下方法。
我想这个问题可能是由估计的项目大小引起的,但是如果没有它,它就会崩溃。
final class CustomCell: UICollectionViewCell {
...
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
let optimalSize = systemLayoutSizeFitting(UIView.layoutFittingExpandedSize)
var newFrame = layoutAttributes.frame
newFrame.size.width = optimalSize.width + 10
layoutAttributes.frame = newFrame
return layoutAttributes
}
...
}
class CustomCollectionViewLayout: UICollectionViewFlowLayout {
override func prepare() {
guard isInitialSetupDone else {
scrollDirection = .horizontal
estimatedItemSize = CGSize(width: 30, height: 40)
minimumInteritemSpacing = 23.3
isInitialSetupDone = true
return
}
// Set sectionInset after invalidation of all items
guard
cache.count == numberOfItems,
let firstItem = cache.first,
let lastItem = cache.last else { return }
let contentSize = collectionViewContentSize
let leftInset : CGFloat = (width - firstItem.frame.width) / 2
let rightInset : CGFloat = (width - lastItem.frame.width) / 2
sectionInset = UIEdgeInsets(top: 3.6, left: leftInset, bottom: 3.6, right: rightInset)
cache.removeAll(keepingCapacity: true)
}
override func shouldInvalidateLayout(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes,
withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> Bool {
let hasOnlyOneItem = (numberOfItems == 1)
let allItemsInvalidated = (cache.count == numberOfItems)
if hasOnlyOneItem {
return true
} else if allItemsInvalidated {
return false
} else {
return true
}
}
override func invalidationContext(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes,
withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutInvalidationContext {
let context = super.invalidationContext(forPreferredLayoutAttributes: preferredAttributes, withOriginalAttributes: originalAttributes)
cache.append(preferredAttributes)
return context
}
}