我有一个集合视图,其中有一个带有标题的部分,每个部分都有一些单词。单词的大小不同。
由于单词大小不同,我添加了以下内容,以防止长单词被截断:layout.estimatedItemSize = CGSize(width: 1.0, height: 1.0)
但是,在设置并调用 reloadData(( 后,单元格(单词(不会仅加载部分(标题(。
但是滚动后,屏幕外的所有部分将加载它们的单词。但是,当我不使用layout.estimatedItemSize时,它可以正常工作,但单词被切断了。
所以我的问题是,是否有另一种方法可以显示这些单词(基本上是一个带有标签的小视图(,而不会将它们切断。还是我错误地使用了估计大小?
正如我从苹果本身的文档中读到的那样:文档 此属性的默认值为 CGSizeZero。将其设置为任何其他值会导致集合视图使用单元格的 preferredLayoutAttributesFitting(_:( 方法查询每个单元格的实际大小。
我确实动态和静态地设置约束(故事板(, 我的动态约束如下:
if prevCell != nil {
let constraint = NSLayoutConstraint(item: cell, attribute: NSLayoutAttribute.leading, relatedBy: NSLayoutRelation.equal, toItem: prevCell, attribute: NSLayoutAttribute.trailing, multiplier: 1.0, constant: 5.0)
cell.addConstraint(constraint)
self.prevCell = cell
}
到目前为止,我自己尝试过的事情:
//before reload data invalidate the layout
self.collectionView!.collectionViewLayout.invalidateLayout()
self.collectionView!.reloadData()
经过更多的研究,找到了处理这个问题的正确方法。 我忘了覆盖单元格类中的 preferredLayoutAttributesFit。为了使它工作,我只是将layout.estimatedItemSize = CGSize(width: 1.0, height: 1.0)
保留在集合视图的viewDidLoad中。
但是,不知何故,这还不够,因为除非您将其滚动出屏幕,否则它将无法计算出正确的大小。它背后可能有一些我不知道的逻辑。
但是当覆盖首选布局属性拟合如下时:
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
setNeedsLayout()
layoutIfNeeded()
let updatedSize = contentView.systemLayoutSizeFitting(layoutAttributes.size)
var updatedFrame = layoutAttributes.frame
updatedFrame.size.width = CGFloat(ceilf(Float(updatedSize.width)))
updatedFrame.size.height = CGFloat(ceilf(Float(updatedSize.height)))
layoutAttributes.frame = updatedFrame
return layoutAttributes
}