UICollectionViewLayout中两个方法的疑惑
澳门美高梅官网
澳门美高梅官网
当前位置 : 澳门美高梅官网 > 澳门美高梅官方网站

UICollectionViewLayout中两个方法的疑惑

在使用自定义UICollectionViewLayout的时候有两个方法可以返回自定义的UICollectionViewLayoutAttributes:

-UICollectionViewLayoutAttributes *layoutAttributesForItemAtIndexPath:NSIndexPath *indexPath

返回rect中的所有的元素的布局属性

-NSArray *layoutAttributesForElementsInRect:CGRectrect

返回对应于indexPath的位置的cell的布局属性

那么问题来了,这两个方法到底区别是什么?我看了一些自定义布局的例子,有的重写了两个方法,而有的只重写了第二个方法,比如说下面的这个例子

import UIKit

protocol PinterestLayoutDelegate {

  func collectionViewcollectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: NSIndexPath, withWidth width: CGFloat -> CGFloat
  func collectionViewcollectionView: UICollectionView, heightForAnnotationAtIndexPath indexPath: NSIndexPath, withWidth width: CGFloat -> CGFloat

}

class PinterestLayoutAttributes: UICollectionViewLayoutAttributes {

  var photoHeight: CGFloat = 0

  override func copyWithZonezone: NSZone -> AnyObject {
    let copy = super.copyWithZonezone as! PinterestLayoutAttributes
    copy.photoHeight = photoHeight
    return copy
  }

  override func isEqualobject: AnyObject? -> Bool {
    if let attributes = object as? PinterestLayoutAttributes {
      if attributes.photoHeight == photoHeight {
        return super.isEqualobject
      }
    }
    return false
  }

}

class PinterestLayout: UICollectionViewLayout {

  var cellPadding: CGFloat = 0
  var delegate: PinterestLayoutDelegate!
  var numberOfColumns = 2

  private var cache = [PinterestLayoutAttributes]
  private var contentHeight: CGFloat = 0
  private var width: CGFloat {
    get {
      let insets = collectionView!.contentInset
      return CGRectGetWidthcollectionView!.bounds - insets.left + insets.right
    }
  }

  override class func layoutAttributesClass -> AnyClass {
    return PinterestLayoutAttributes.self
  }

  override func collectionViewContentSize -> CGSize {
    return CGSizewidth: width, height: contentHeight
  }

  override func prepareLayout {
    if cache.isEmpty {
      let columnWidth = width / CGFloatnumberOfColumns

      var xOffsets = [CGFloat]
      for column in 0..<numberOfColumns {
        xOffsets.appendCGFloatcolumn * columnWidth
      }

      var yOffsets = [CGFloat]count: numberOfColumns, repeatedValue: 0

      var column = 0
      for item in 0..<collectionView!.numberOfItemsInSection0 {
        let indexPath = NSIndexPathforItem: item, inSection: 0

        let width = columnWidth - cellPadding * 2
        let photoHeight = delegate.collectionViewcollectionView!, heightForPhotoAtIndexPath: indexPath, withWidth: width
        let annotationHeight = delegate.collectionViewcollectionView!, heightForAnnotationAtIndexPath: indexPath, withWidth: width
        let height = cellPadding + photoHeight + annotationHeight + cellPadding

        let frame = CGRectx: xOffsets[column], y: yOffsets[column], width: columnWidth, height: height
        let insetFrame = CGRectInsetframe, cellPadding, cellPadding
        let attributes = PinterestLayoutAttributesforCellWithIndexPath: indexPath
        attributes.frame = insetFrame
        attributes.photoHeight = photoHeight
        cache.appendattributes
        contentHeight = maxcontentHeight, CGRectGetMaxYframe
        yOffsets[column] = yOffsets[column] + height
        column = column >= numberOfColumns - 1 ? 0 : ++column
      }
    }
  }

  override func layoutAttributesForElementsInRectrect: CGRect -> [AnyObject]? {
    var layoutAttributes = [UICollectionViewLayoutAttributes]
    for attributes in cache {
      if CGRectIntersectsRectattributes.frame, rect {
        layoutAttributes.appendattributes
      }
    }
    return layoutAttributes
  }

}

这个自定义PinterestLayout中,PinterestLayoutAttributesUICollectionViewLayoutAttributes的子类)是创建在preparelayout中而不是在layoutAttributesForItemAtIndexPath中的,用一个cache的数组保存起来,然后layoutAttributesForElementsInRect返回这个数组,那么为什么这个例子中layoutAttributesForItemAtIndexPath没有被用到呢?我被这两个方法搞糊涂了。

layoutAttributesForElementsInRect:的rect是可见部分的rect;layoutAttributesForItemAtIndexPath:是对于任意indexpath而言的。前面一个的实现往往依赖于后者,根据rect取得可见的indexpath,再根据后者取得layout attributes,加入数组,然后返回。

广告位

澳门美高梅官网