ios - 优化 UICollectionView 的性能

标签 ios swift uicollectionview uicollectionviewcell

我需要动态计算 UICollectionView 的单元格高度。我正在使用这个功能

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

问题是它在显示之前返回每个单元格的大小。如果数组中有 120 个项目,它将在

之前计算 120 个单元格大小
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell

被调用。这造成了很大的性能问题。加载整个集合需要 10 秒。如果我不使用 sizeforitematindexpath,集合将在 1 秒内加载。我该如何解决这个问题?

我正在使用 Xcode 8.3.3 和 Swift 3.0

这是我对第一个委托(delegate)的确切代码

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let json = JSON(mySources[indexPath.row])
        var url = NSURL(string: json["cover"]["source"].stringValue)

        var data = NSData(contentsOf: url as! URL)
        var photo = UIImage(data: data as! Data)

        var height1 = photo?.size.height


        var boundingRect = CGRect(x:0, y:0, width: 372, height: CGFloat(MAXFLOAT))
        let rect = AVMakeRect(aspectRatio: (photo?.size)!, insideRect: boundingRect)

        let imageHeight = rect.height

        let font = UIFont(name: "Raleway-SemiBold", size: 17)
        let titleHeight = heightForLabel(text: json["name"].stringValue, font: font!, width: 160)
        let restaurantHeight = heightForLabel(text: json["place"]["name"].stringValue, font: font!, width: 160)
        print(restaurantHeight + titleHeight + imageHeight)
        return CGSize(width: 372, height:imageHeight + titleHeight + restaurantHeight + 100)


   }

最佳答案

UICollectionViewFlowLayout 总是在开始准备单元格之前一次性计算所有单元格的大小。

但是,如果我没记错的话,您可以通过为其 estimatedItemSize 属性设置一个非零值来防止这种情况(文档对此并不十分清楚):

The estimated size of cells in the collection view.

Providing an estimated cell size can improve the performance of the collection view when the cells adjust their size dynamically. Specifying an estimate value lets the collection view defer some of the calculations needed to determine the actual size of its content. Specifically, cells that are not onscreen are assumed to be the estimated height.

The default value of this property is CGSizeZero. Setting it to any other value causes the collection view to query each cell for its actual size using the cell’s preferredLayoutAttributesFitting(_:) method. If all of your cells are the same height, use the itemSize property, instead of this property, to specify the cell size instead.

因此调用下一段代码可能会解决您的性能问题:

(collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.estimatedItemSize = CGSize(width: 375.0, height: 44.0)

关于ios - 优化 UICollectionView 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45601610/

相关文章:

ios - 无法使标识符为 "GroupMessageCell"的单元格出队

swift - 具有通用协议(protocol)的 VIPER 架构

swift - Google Maps iOS SDK map 不会出现

ios - 当 uicollectionview 单元格选择时,另一个 viewcontroller 中的 uiLabel 不会更新

iphone - 如何获取 iPhone OS 中的所有图标?

ios - 如何像 Facebook instagram 一样标记 imageview。在 ios 中(在 imageview 上标记坐标)

android - 如何在 React Native 中监听 App 的启动和关闭?

iOS:无法更改水平堆栈 View 中的宽度

ios - UICollectionView 消失

ios - 在 UICollectionViewController header 上添加 UISearchBar