2016-03-12 73 views
4

我已經實現了自定義FlowLayout子,這顯然已經排除我經由storyboard加入headerView(複選框消失)時加入HeaderView到的CollectionView。有沒有其他的方法可以使用storyboards使用自定義的FlowLayout(SWIFT)

有關於如何添加headerView編程一些答案,但他們在objective-C,我怎麼可以添加一個使用Swift

以下不會產生頭部看法,我想不通爲什麼?

CollectionViewController { 


    override func viewDidLoad() { 
     super.viewDidLoad() 

      // Setup Header 
     self.collectionView!.registerClass(PinHeaderView.self, forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: headerIdentifier) 

} 
    override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView { 
       //1 
       switch kind { 
        //2 
       case UICollectionElementKindSectionHeader: 
        //3 
        let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind,withReuseIdentifier: "PinHeaderView", 
         forIndexPath: indexPath) 
         as! PinHeaderView 
        headerView.pinHeaderLabel.text = boardName 
        return headerView 
       default: 
        //4 
        fatalError("Unexpected element kind") 
       } 
     } 
    } 

class PinHeaderView: UICollectionReusableView { 


    @IBOutlet weak var pinHeaderLabel: UILabel! 



} 

我的佈局類:

import UIKit 
protocol PinterestLayoutDelegate { 
    // 1. Method to ask the delegate for the height of the image 
    func collectionView(collectionView:UICollectionView, heightForPhotoAtIndexPath indexPath:NSIndexPath , withWidth:CGFloat) -> CGFloat 
    // 2. Method to ask the delegate for the height of the annotation text 
    func collectionView(collectionView: UICollectionView, heightForAnnotationAtIndexPath indexPath: NSIndexPath, withWidth width: CGFloat) -> CGFloat 

    func columnsForDevice() -> Int 

} 

class PinterestLayoutAttributes:UICollectionViewLayoutAttributes { 

    // 1. Custom attribute 
    var photoHeight: CGFloat = 0.0 
    var headerHeight: CGFloat = 0.0 

    // 2. Override copyWithZone to conform to NSCopying protocol 
    override func copyWithZone(zone: NSZone) -> AnyObject { 
     let copy = super.copyWithZone(zone) as! PinterestLayoutAttributes 
     copy.photoHeight = photoHeight 
     return copy 
    } 

    // 3. Override isEqual 
    override func isEqual(object: AnyObject?) -> Bool { 
     if let attributtes = object as? PinterestLayoutAttributes { 
      if(attributtes.photoHeight == photoHeight ) { 
       return super.isEqual(object) 
      } 
     } 
     return false 
    } 
} 


class PinterestLayout: UICollectionViewLayout { 
    //1. Pinterest Layout Delegate 
    var delegate:PinterestLayoutDelegate! 

    //2. Configurable properties 
    //moved numberOfColumns 
    var cellPadding: CGFloat = 6.0 

    //3. Array to keep a cache of attributes. 
    private var cache = [PinterestLayoutAttributes]() 

    //4. Content height and size 
    private var contentHeight:CGFloat = 0.0 
    private var contentWidth: CGFloat { 
     let insets = collectionView!.contentInset 
     return CGRectGetWidth(collectionView!.bounds) - (insets.left + insets.right) 
    } 

    override class func layoutAttributesClass() -> AnyClass { 

     return PinterestLayoutAttributes.self 


    } 

    override func prepareLayout() { 
     // 1. Only calculate once 
     //if cache.isEmpty { 

      // 2. Pre-Calculates the X Offset for every column and adds an array to increment the currently max Y Offset for each column 
      let numberOfColumns = delegate.columnsForDevice() 
      let columnWidth = contentWidth/CGFloat(numberOfColumns) 
      var xOffset = [CGFloat]() 
      for column in 0 ..< numberOfColumns { 
       xOffset.append(CGFloat(column) * columnWidth) 
      } 
      var column = 0 
      var yOffset = [CGFloat](count: numberOfColumns, repeatedValue: 0) 

      // 3. Iterates through the list of items in the first section 
      for item in 0 ..< collectionView!.numberOfItemsInSection(0) { 

       let indexPath = NSIndexPath(forItem: item, inSection: 0) 

       // 4. Asks the delegate for the height of the picture and the annotation and calculates the cell frame. 
       let width = columnWidth - cellPadding*2 
       let photoHeight = delegate.collectionView(collectionView!, heightForPhotoAtIndexPath: indexPath , withWidth:width) 
       let annotationHeight = delegate.collectionView(collectionView!, heightForAnnotationAtIndexPath: indexPath, withWidth: width) 
       let height = cellPadding + photoHeight + annotationHeight + cellPadding 
       let frame = CGRect(x: xOffset[column], y: yOffset[column], width: columnWidth, height: height) 
       let insetFrame = CGRectInset(frame, cellPadding, cellPadding) 

       // 5. Creates an UICollectionViewLayoutItem with the frame and add it to the cache 
       let attributes = PinterestLayoutAttributes(forCellWithIndexPath: indexPath) 
       attributes.photoHeight = photoHeight 
       attributes.frame = insetFrame 
       cache.append(attributes) 

       // 6. Updates the collection view content height 
       contentHeight = max(contentHeight, CGRectGetMaxY(frame)) 
       yOffset[column] = yOffset[column] + height 

       column = column >= (numberOfColumns - 1) ? 0 : ++column 
      } 
     //} 
    } 


    override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? { 

     let attributes = PinterestLayoutAttributes(forSupplementaryViewOfKind: elementKind, withIndexPath: indexPath) 
    attributes.headerHeight = 100.0 
    attributes.frame = (self.collectionView?.frame)! 
    return attributes 



    } 


    override func collectionViewContentSize() -> CGSize { 
     return CGSize(width: contentWidth, height: contentHeight) 
    } 

    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 

     var layoutAttributes = [UICollectionViewLayoutAttributes]() 

     // Loop through the cache and look for items in the rect 
     for attributes in cache { 
      if CGRectIntersectsRect(attributes.frame, rect) { 
       layoutAttributes.append(attributes) 
      } 
     } 
     return layoutAttributes 
    } 
} 
+0

您是否看到過Apple的高級集合視圖示例代碼? – Andrea

+0

謝謝,我只是檢查了它,但它在Obj-C =( – GarySabo

回答

3

您可以添加標題視圖故事板,將一個「收集可重複使用的視圖」,並將其放在裏面的CollectionView,然後將其class和故事板identifier。或者,您可以按照代碼中所示以編程方式註冊自定義標頭類。

self.collectionView!.registerClass(PinHeaderView.self, forSupplementaryViewOfKind:UICollectionElementKindSectionHeader, withReuseIdentifier: headerIdentifier)

viewForSupplementaryElementOfKind委託方法是不完整的,情況UICollectionElementKindSectionFooter沒有被處理,做頁腳視圖一樣的,你做了什麼的頭視圖。如果您沒有看到它,請將標題視圖的圖層的borderWidth設置爲大於0的值,它可能會顯示出來。

+1

謝謝,但(1)我不能拖動'reusableView',因爲Xcode不會讓我把它放在'CollectionViewController'中的任何地方,(2 )我有一個破發點中的'viewFOrSupplementaryElementOfKind'設置和它沒有得到根本當前調用。 – GarySabo

+0

@GarySabo,在故事板,最左邊的面板上,你可以看到集合視圖控制器,其下有一個集合視圖,嘗試刪除 – gabbler

+0

這就是我試過的,Xcode不會讓我:( – GarySabo

1

爲什麼在方法layoutAttributesForSupplementaryViewOfKind中使用PinterestLayoutAttributes(forCellWithIndexPath: indexPath)?您可以使用PinterestLayoutAttributes(forSupplementaryViewOfKind elementKind: String, withIndexPath indexPath: NSIndexPath)

要生成佈局屬性的細胞,而不是suplementary視圖。因此,您的佈局屬性不包含正確的類別類型和視圖類型。這就是爲什麼即使你註冊了充足視圖的類 - 集合視圖不會佈局它的實例。

+0

好,我已經編輯了我的問題,但它仍然沒有給我一個頭。 – GarySabo

1

裏面的prepareForLayout功能爲頭添加一個attributes對象。您可以將其追加到緩存中,如下所示:

 // Add Attributes for section header 
     let headerAtrributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, with: IndexPath(item: 0, section: 0)) 
     headerAtrributes.frame = CGRect(x: 0, y: 0, width: self.collectionView!.bounds.size.width, height: 50) 
     cache.append(headerAtrributes)