优化UICollectionView的性能

时间:2017-08-09 22:32:12

标签: 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

这是第一个代表的确切代码

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)


   }

2 个答案:

答案 0 :(得分:1)

在开始准备细胞之前,

UICollectionViewFlowLayout总是一次计算所有细胞的大小。

但是,如果我记得很清楚,你可以通过为其estimatedItemSize属性设置一个非零值来防止这种情况(文档不清楚):

  

集合视图中估计的单元格大小。

     

当单元格动态调整其大小时,提供估计的单元格大小可以提高集合视图的性能。通过指定估计值,集合视图可以推迟确定其内容实际大小所需的一些计算。具体而言,假设不在屏幕上的单元格是估计的高度。

     

此属性的默认值为CGSizeZero。将其设置为任何其他值会导致集合视图使用单元格的preferredLayoutAttributesFitting(_ :)方法查询每个单元格的实际大小。如果所有单元格的高度相同,请使用itemSize属性而不是此属性来指定单元格大小。

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

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

答案 1 :(得分:0)

您应该使用可重复使用的单元格,以便您的集合视图不会一次加载所有数据,而只会加载屏幕上的数据。这比总数少得多。这将节省性能,内存,并将减少CPU使用(图形更平滑,电池消耗更少)。

如何:

为您的collectionView:

menuCollectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MenuCell")
函数cellForItemAtIndexPath中的

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MenuCell", for: indexPath as IndexPath)

         return cell
}

希望这有帮助!