UICollectionView .reloadData() 只显示部分

UICollectionView .reloadData() only shows sections

我有一个 collection 视图,其中有一个带有标题的部分,每个部分都有一些文字。单词大小不一。

因为单词的大小不同,我添加了以下内容,以防止长单词被截断:layout.estimatedItemSize = CGSize(width: 1.0, height: 1.0)

但是在设置并调用 reloadData() 之后,单元格(单词)不会仅加载部分(标题)。

但是在滚动之后,所有超出屏幕的部分都会加载他们的话。但是,当我不使用 layout.estimatedItemSize 时,它可以正常工作,但单词会被截断。

所以我的问题是是否有另一种方式来显示这些词(基本上是带有标签的小视图)而不被截断。还是我错误地使用了 estimatedSize?

正如我从苹果本身的文档中读到的那样:docs 此 属性 的默认值为 CGSizeZero。将其设置为任何其他值会导致 collection 视图使用单元格的 preferredLayoutAttributesFitting(_:) 方法查询每个单元格的实际大小。

我确实动态和静态地设置约束(StoryBoard), 我的动态约束如下:

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()

经过更多研究,找到了处理此问题的正确方法。 我忘记覆盖单元格 class 中的 preferredLayoutAttributesFitting。为了让它工作,我只是在集合视图的 viewDidLoad 中留下了 layout.estimatedItemSize = CGSize(width: 1.0, height: 1.0)

然而,这还不够,因为直到您将其滚动出屏幕,它才能计算出正确的尺寸。它背后可能有一些我不知道的逻辑。

但是当如下覆盖 preferredLayoutAttributesFitting 时:

    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
    }