【问题标题】:Faster way to estimate cell height in a CollectionView在 CollectionView 中估计单元格高度的更快方法
【发布时间】:2018-05-24 22:18:24
【问题描述】:

我的 UICollectionView 中有一个无限滚动,我注意到我估计单元格高度的方式是我的集合视图的瓶颈。我滚动收藏视图越多,它就会导致一些长时间的延迟。

有没有更好的方法来估计我的单元格的高度?

单元格有不同的高度,因为我在每个单元格中都有一个UILabel。我为这些 UILabel 分配了一个不同长度的 NSMutableAttributedStrings:

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .justified
paragraphStyle.lineSpacing = 5.0

let attributedText = NSMutableAttributedString(string: "   \(post.caption)", attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 15), .paragraphStyle: paragraphStyle, .baselineOffset: NSNumber(value: 0)])

attributedText.append(NSAttributedString(string: "\n\n", attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 4)]))

let timeAgoDisplay = post.creationDate.timeAgoDisplay()
attributedText.append(NSAttributedString(string: timeAgoDisplay, attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 14), NSAttributedStringKey.foregroundColor: UIColor.storiesLightGray()]))

captionLabel.attributedText = attributedText

我的sizeForItemAt 方法。我注意到,一旦我的收藏视图中有 200 多个项目,调用 dummyCell.layoutIfNeeded() 会使我的应用程序非常慢:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        var height: CGFloat = 180

        let frame = CGRect(x: 0, y: 0, width: view.frame.width, height: height)
        let dummyCell = HomePostCell(frame: frame)

        dummyCell.post = presenter.posts[indexPath.item]
        dummyCell.layoutIfNeeded()

        let targetSize = CGSize(width: view.frame.width, height: 5000)
        let estimatedSize = dummyCell.systemLayoutSizeFitting(targetSize)

        let newHeight = max(height, estimatedSize.height)

        return CGSize(width: view.frame.width, height: newHeight)
 }

谢谢!

【问题讨论】:

    标签: ios swift uicollectionview cgsize


    【解决方案1】:

    理想情况下,您不应在sizeForItemAt 中使用systemLayoutSizeFitting,因为正如您所说,它很慢。

    您可以预先缓存一些单元格数据,计算大小,然后将它们存储在一个数组或类似的数组中,这样sizeForItemAt 只需在数组中进行查找——这很快。

    你也不需要使用systemLayoutSizeFitting;您可以使用您对标签大小和内容的了解来计算大小(例如使用 NSAttributedString 测量方法)。

    这是我们在systemLayoutSizeFitting 或自动布局出现之前所做的事情,而且速度要快得多。

    【讨论】:

    • 参见我的讨论:apeth.com/iOSBook/ch21.html#_variable_row_heights 这是关于表视图行,而不是集合视图项,但想法完全相同。
    • @matt Precache 表示:在重新加载集合视图之前,根据字符串大小计算单元格的大小并将它们存储在数组中。并在 `sizeForItemAt' 中使用该计算数组,对吗?
    猜你喜欢
    • 2017-12-28
    • 1970-01-01
    • 2018-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    相关资源
    最近更新 更多