如何子类化UICollectionViewFlowLayout以便可以覆盖layoutAttributesForElementsInRect

时间:2015-05-20 05:48:58

标签: ios swift xcode6

我想创建一个垂直的无限滚动,在阅读之后,很多教程都明白我需要继承UICollectionViewFlowLayout。问题是我不完全明白该怎么做。

我试过以下: 1.创建一个新类newView并将其分配给属性检查器自定义类部分中的视图控制器。

class newView: UICollectionViewController,
UICollectionViewDataSource, UICollectionViewDelegate {
  1. 在此类中实现(覆盖)cellForItemAtIndexPath和sizeForItemAtIndexPath,它可以正常工作。到目前为止,我有一个垂直滚动视图,包含1行中的2个项目。但是我在两行之间有不等的空格。布置前2个项目后,第三个项目的垂直位置低于前两个项目中的较长项目,如下所示: enter image description here
  2. 我已经阅读了许多SO线程,讨论并建议继承UICollectionViewFlowLayout并覆盖layoutAttributesForElementsInRect方法以进行所需的显示。但是当我尝试在我的视图控制器中添加流布局时,如下所示,它给了我错误:

    class DiscoverView: UICollectionViewController, UICollectionViewFlowLayout,
    UICollectionViewDataSource, UICollectionViewDelegate {
    

    然后我认为它可能是我的视图布局需要是子类而不是控制器,所以我尝试创建一个单独的类,如下所示:

    class newViewLayout: UICollectionViewFlowLayout {
    
    override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
        return super.layoutAttributesForElementsInRect(rect)
    }
    

    然后我尝试将此类分配给我的视图布局。但它并没有出现在自定义类部分(属性检查器)下。它也不会出现在属性检查器中>集合视图>布局>设置自定义>类

    我知道这是一个非常基本和愚蠢的错误,但不确定我在概念上做错了什么。

2 个答案:

答案 0 :(得分:0)

虽然这是旧的,但我不想添加使其适用于我的解决方案:)

您应该在viewDidLoad中添加子类,如:

collectionView?.collectionViewLayout = YourCustomClass

答案 1 :(得分:0)

您需要覆盖在主类中声明的布局

let flowLayout = flowLayoutClass()

override func viewDidLoad() {
    super.viewDidLoad()
    collectionView.collectionViewFlowLayout = flowLayout
}

class flowLayoutClass: UICollectionViewFlowLayout {
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    let arr = super.layoutAttributesForElements(in: rect)

    for atts:UICollectionViewLayoutAttributes in arr! {
        if nil == atts.representedElementKind {
            let ip = atts.indexPath
            atts.frame = (self.layoutAttributesForItem(at: ip)?.frame)!
        }
    }
    return arr
  }

  override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
    let atts = super.layoutAttributesForItem(at: indexPath)

    if indexPath.item == 0 || indexPath.item == 1 {
        var frame = atts?.frame;
        frame?.origin.y = sectionInset.top;
        atts?.frame = frame!;
        return atts
    }

    let ipPrev = IndexPath(item: indexPath.item - 2, section: indexPath.section)

    let fPrev = self.layoutAttributesForItem(at: ipPrev)?.frame

    let rightPrev = (fPrev?.origin.y)! + (fPrev?.size.height)! + 10

    if (atts?.frame.origin.y)! <= rightPrev {
        return atts
    }

    var f = atts?.frame
    f?.origin.y = rightPrev
    atts?.frame = f!
    return atts
  }
}