2014-12-05 14 views
12

Sto provando a creare un'intestazione aggiuntiva adesiva, che rimane sempre in alto e non risponde agli eventi di scorrimento. Le soluzioni che ho trovato finora reagiscono ancora sullo scrolling del bounch e vengono risolte usando un flowlayout personalizzato, che probabilmente sarà anche la soluzione per il mio problema.UICollectionView sticky header in swift

Il motivo per cui lo voglio in questo modo, è che l'intestazione è utilizzata in altri posti e dovrebbe essere riutilizzabile. Spero che questo possa essere risolto in questo modo e non devo creare una vista separata.

Come sto facendo questo in Swift, sarebbe bello avere un esempio in Swift.

risposta

5

La soluzione finale ho trovato:

Usando questo layout di flusso personalizzato è stato possibile risolvere questa intestazione appiccicoso:

class StickyHeaderCollectionViewFlowLayout: UICollectionViewFlowLayout { 

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

     var superAttributes: [UICollectionViewLayoutAttributes]? = super.layoutAttributesForElementsInRect(rect) as? [UICollectionViewLayoutAttributes] 

     if superAttributes == nil { 
      // If superAttributes couldn't cast, return 
      return super.layoutAttributesForElementsInRect(rect) 
     } 

     let contentOffset = collectionView!.contentOffset 
     var missingSections = NSMutableIndexSet() 

     for layoutAttributes in superAttributes! { 
      if (layoutAttributes.representedElementCategory == .Cell) { 
       if let indexPath = layoutAttributes.indexPath { 
        missingSections.addIndex(layoutAttributes.indexPath.section) 
       } 
      } 
     } 

     for layoutAttributes in superAttributes! { 
      if let representedElementKind = layoutAttributes.representedElementKind { 
       if representedElementKind == UICollectionElementKindSectionHeader { 
        if let indexPath = layoutAttributes.indexPath { 
         missingSections.removeIndex(indexPath.section) 
        } 
       } 
      } 
     } 

     missingSections.enumerateIndexesUsingBlock { idx, stop in 
      let indexPath = NSIndexPath(forItem: 0, inSection: idx) 
      if let layoutAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: indexPath) { 
       superAttributes!.append(layoutAttributes) 
      } 
     } 

     for layoutAttributes in superAttributes! { 
      if let representedElementKind = layoutAttributes.representedElementKind { 
       if representedElementKind == UICollectionElementKindSectionHeader { 
        let section = layoutAttributes.indexPath!.section 
        let numberOfItemsInSection = collectionView!.numberOfItemsInSection(section) 

        let firstCellIndexPath = NSIndexPath(forItem: 0, inSection: section)! 
        let lastCellIndexPath = NSIndexPath(forItem: max(0, (numberOfItemsInSection - 1)), inSection: section)! 


        let (firstCellAttributes: UICollectionViewLayoutAttributes, lastCellAttributes: UICollectionViewLayoutAttributes) = { 
         if (self.collectionView!.numberOfItemsInSection(section) > 0) { 
          return (
           self.layoutAttributesForItemAtIndexPath(firstCellIndexPath), 
           self.layoutAttributesForItemAtIndexPath(lastCellIndexPath)) 
         } else { 
          return (
           self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: firstCellIndexPath), 
           self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionFooter, atIndexPath: lastCellIndexPath)) 
         } 
         }() 

        let headerHeight = CGRectGetHeight(layoutAttributes.frame) 
        var origin = layoutAttributes.frame.origin 

        origin.y = min(contentOffset.y, (CGRectGetMaxY(lastCellAttributes.frame) - headerHeight)) 
        // Uncomment this line for normal behaviour: 
        // origin.y = min(max(contentOffset.y, (CGRectGetMinY(firstCellAttributes.frame) - headerHeight)), (CGRectGetMaxY(lastCellAttributes.frame) - headerHeight)) 

        layoutAttributes.zIndex = 1024 
        layoutAttributes.frame = CGRect(origin: origin, size: layoutAttributes.frame.size) 
       } 
      } 
     } 

     return superAttributes 
    } 

    override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { 
     return true 
    } 

} 

Per creare un layout in cui le intestazioni sono appiccicosi come tradizione, il cambiamento questa linea:

origin.y = min(contentOffset.y, (CGRectGetMaxY(lastCellAttrs.frame) - headerHeight)) 

a questa linea:

origin.y = min(max(contentOffset.y, (CGRectGetMinY(firstCellAttrs.frame) - headerHeight)), (CGRectGetMaxY(lastCellAttrs.frame) - headerHeight)) 

Sperando che questo sia utile per gli altri!

Aggiornamento

aggiornato per correggere un crash (grazie a Robert Atkins!) E alcuni aggiornamenti Swift 1.2

TVOS & iOS 9

TVOS e iOS 9 ha introdotto la proprietà sectionHeadersPinToVisibleBounds che può essere utilizzato

+0

Ricevo un incidente EXC_ARITHMETIC sulla linea 'firstCellAttrs = ...', forse qualcosa legato alla http://stackoverflow.com/questions/24616797/uicollectionviewflowlayout-subclass-crashes-accessing-array- oltre-limite-mentre? –

+0

Apparentemente questo non funziona per me: Xcode 6.1.1 e iOS 8 :-(Qualche idea? Potresti fare un nuovo test per favore? L'intestazione dovrebbe rimanere in cima come in https://github.com/jamztang/CSStickyHeaderFlowLayout right ? – blackjacx

+0

Non funziona per me arresti anomali qui 'self.layoutAttributesForSupplementaryViewOfKind (UICollectionElementKindSectionFooter, atIndexPath: lastCellIndexPath))' –

2

Ho risolto il problema verificando il test per le sezioni vuote come suggerito in this gist. Ho anche aggiunto un paio di if let s per punti stile Swift extra ;-). Questo ora funziona per me:

class StickyHeaderCollectionViewFlowLayout: UICollectionViewFlowLayout { 

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

     var answer: [UICollectionViewLayoutAttributes] = super.layoutAttributesForElementsInRect(rect)! as [UICollectionViewLayoutAttributes] 
     let contentOffset = collectionView!.contentOffset 

     var missingSections = NSMutableIndexSet() 

     for layoutAttributes in answer { 
      if (layoutAttributes.representedElementCategory == .Cell) { 
       if let indexPath = layoutAttributes.indexPath { 
        missingSections.addIndex(layoutAttributes.indexPath.section) 
       } 
      } 
     } 

     for layoutAttributes in answer { 
      if let representedElementKind = layoutAttributes.representedElementKind { 
       if representedElementKind == UICollectionElementKindSectionHeader { 
        if let indexPath = layoutAttributes.indexPath { 
         missingSections.removeIndex(indexPath.section) 
        } 
       } 
      } 
     } 

     missingSections.enumerateIndexesUsingBlock { idx, stop in 
      let indexPath = NSIndexPath(forItem: 0, inSection: idx) 
      if let layoutAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: indexPath) { 
       answer.append(layoutAttributes) 
      } 
     } 

     for layoutAttributes in answer { 
      if let representedElementKind = layoutAttributes.representedElementKind { 
       if representedElementKind == UICollectionElementKindSectionHeader { 
        let section = layoutAttributes.indexPath!.section 
        let numberOfItemsInSection = collectionView!.numberOfItemsInSection(section) 

        let firstCellIndexPath = NSIndexPath(forItem: 0, inSection: section)! 
        let lastCellIndexPath = NSIndexPath(forItem: max(0, (numberOfItemsInSection - 1)), inSection: section)! 


        let (firstCellAttributes: UICollectionViewLayoutAttributes, lastCellAttributes: UICollectionViewLayoutAttributes) = { 
         if (self.collectionView!.numberOfItemsInSection(section) > 0) { 
          return (
           self.layoutAttributesForItemAtIndexPath(firstCellIndexPath), 
           self.layoutAttributesForItemAtIndexPath(lastCellIndexPath)) 
         } else { 
          return (
           self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: firstCellIndexPath), 
           self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionFooter, atIndexPath: lastCellIndexPath)) 
         } 
        }() 

        let headerHeight = CGRectGetHeight(layoutAttributes.frame) 
        var origin = layoutAttributes.frame.origin 

        origin.y = min(max(contentOffset.y, (CGRectGetMinY(firstCellAttributes.frame) - headerHeight)), (CGRectGetMaxY(lastCellAttributes.frame) - headerHeight)) 

        layoutAttributes.zIndex = 1024 
        layoutAttributes.frame = CGRect(origin: origin, size: layoutAttributes.frame.size) 
       } 
      } 
     } 

     return answer 
    } 

    override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { 
     return true 
    } 

} 
+1

Grazie per quello! Ho aggiornato la mia risposta con la parte aggiornata del codice. – Antoine

+0

Grazie! Cordiali saluti, in Swift 1.2 la prima riga di layoutAttributesForElementsIntRect richiede ora un "come!" var risposta: [UICollectionViewLayoutAttributes] = super.layoutAttributesForElementsInRect (rect)! come! [UICollectionViewLayoutAttributes] –

+0

Ho ottenuto una "definizione conflitti con il valore precedente" a 'let (firstCellAttributes: UICollectionViewLayoutAttributes, lastCellAttributes: UICollectionViewLayoutAttributes) = {' in swift 2.0 – Liumx31

-2

lo uso nel mio progetto. Spero che sia d'aiuto.

func collectionView(collectionView: UICollectionView, 
    layout collectionViewLayout: UICollectionViewLayout, 
    referenceSizeForHeaderInSection section: Int) -> CGSize 
{ 
    return CGSizeMake(UIScreen.mainScreen().bounds.width, 40) 
} 

ovviamente. puoi restituire qualsiasi dimensione tu voglia.

+0

questo imposta solo l'altezza dell'intestazione, ma non crea un'intestazione appiccicosa .. – Antoine

1

Ecco una soluzione semplice che funziona se si dispone di una sola sezione.

class StickyHeaderLayout: UICollectionViewFlowLayout { 

    override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { 
    return true 
    } 

    override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? { 
    var attributes = super.layoutAttributesForElementsInRect(rect)! as! [UICollectionViewLayoutAttributes] 

     let offset   = collectionView?.contentOffset 


     for attrs in attributes { 
     if attrs.representedElementKind == nil { 
      let indexPath  = NSIndexPath(forItem: 0, inSection: attrs.indexPath.section) 
      let layoutAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: indexPath) 

      attributes.append(layoutAttributes) 
     } 
     } 

     for attrs in attributes { 
     if attrs.representedElementKind == nil { 
      continue 
     } 

     if attrs.representedElementKind == UICollectionElementKindSectionHeader { 

      var headerRect = attrs.frame 
      headerRect.size.height = headerHeight 
      headerRect.origin.y = offset!.y 
      attrs.frame = headerRect 
      attrs.zIndex = 1024 
      break 
     } 
     } 

    return attributes 
    } 
} 
3

lavori per me con rapida 2,0

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

    var superAttributes:NSMutableArray = NSMutableArray(array: super.layoutAttributesForElementsInRect(rect)!) as NSMutableArray 

    let contentOffset = collectionView!.contentOffset 
    var missingSections = NSMutableIndexSet() 

    for layoutAttributes in superAttributes { 
     if (layoutAttributes.representedElementCategory == .Cell) { 
      if let indexPath = layoutAttributes.indexPath { 
       missingSections.addIndex(layoutAttributes.indexPath.section) 
      } 
     } 
    } 

    for layoutAttributes in superAttributes{ 
     if let representedElementKind = layoutAttributes.representedElementKind { 
      if representedElementKind == UICollectionElementKindSectionHeader { 
       if let indexPath = layoutAttributes.indexPath { 
        missingSections.removeIndex(indexPath.section) 
       } 
      } 
     } 
    } 

    missingSections.enumerateIndexesUsingBlock { idx, stop in 
     let indexPath = NSIndexPath(forItem: 0, inSection: idx) 
     let layoutAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: indexPath) 
     superAttributes.addObject(layoutAttributes!) 
    } 

    for la in superAttributes { 

     let layoutAttributes = la as! UICollectionViewLayoutAttributes; 

     if let representedElementKind = layoutAttributes.representedElementKind { 
      if representedElementKind == UICollectionElementKindSectionHeader { 
       let section = layoutAttributes.indexPath.section 
       let numberOfItemsInSection = collectionView!.numberOfItemsInSection(section) 

       let firstCellIndexPath = NSIndexPath(forItem: 0, inSection: section) 
       let lastCellIndexPath = NSIndexPath(forItem: max(0, (numberOfItemsInSection - 1)), inSection: section)      

       var firstCellAttributes:UICollectionViewLayoutAttributes 
       var lastCellAttributes:UICollectionViewLayoutAttributes 

        if (self.collectionView!.numberOfItemsInSection(section) > 0) { 
          firstCellAttributes = self.layoutAttributesForItemAtIndexPath(firstCellIndexPath)! 
          lastCellAttributes = self.layoutAttributesForItemAtIndexPath(lastCellIndexPath)! 
        } else { 
          firstCellAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: firstCellIndexPath)! 
          lastCellAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionFooter, atIndexPath: lastCellIndexPath)! 
        } 

       let headerHeight = CGRectGetHeight(layoutAttributes.frame) 
       var origin = layoutAttributes.frame.origin 

       origin.y = min(max(contentOffset.y, (CGRectGetMinY(firstCellAttributes.frame) - headerHeight)), (CGRectGetMaxY(lastCellAttributes.frame) - headerHeight)) 
       ; 

       layoutAttributes.zIndex = 1024; 
       layoutAttributes.frame = CGRect(origin: origin, size: layoutAttributes.frame.size) 

      } 
     } 
    } 

    return NSArray(array: superAttributes) as? [UICollectionViewLayoutAttributes] 
} 

override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { 
    return true 
} 
+0

questo codice funziona solo per lo scorrimento verticale, puoi farlo funzionare per lo scorrimento orizzontale? e l'intestazione della sezione in alto? – TomSawyer

1

Cleaner Swift 2.3 versione testata della risposta di Irina

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

    guard var superAttributes = super.layoutAttributesForElementsInRect(rect) else { 
     return super.layoutAttributesForElementsInRect(rect) 
    } 

    let contentOffset = collectionView!.contentOffset 
    let missingSections = NSMutableIndexSet() 

    for layoutAttributes in superAttributes { 
     if (layoutAttributes.representedElementCategory == .Cell) { 
      missingSections.addIndex(layoutAttributes.indexPath.section) 
     } 

     if let representedElementKind = layoutAttributes.representedElementKind { 
      if representedElementKind == UICollectionElementKindSectionHeader { 
       missingSections.removeIndex(layoutAttributes.indexPath.section) 
      } 
     } 
    } 

    missingSections.enumerateIndexesUsingBlock { idx, stop in 
     let indexPath = NSIndexPath(forItem: 0, inSection: idx) 
     if let layoutAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: indexPath) { 
      superAttributes.append(layoutAttributes) 
     } 
    } 

    for layoutAttributes in superAttributes { 
     if let representedElementKind = layoutAttributes.representedElementKind { 
      if representedElementKind == UICollectionElementKindSectionHeader { 
       let section = layoutAttributes.indexPath.section 
       let numberOfItemsInSection = collectionView!.numberOfItemsInSection(section) 

       let firstCellIndexPath = NSIndexPath(forItem: 0, inSection: section) 
       let lastCellIndexPath = NSIndexPath(forItem: max(0, (numberOfItemsInSection - 1)), inSection: section) 

       var firstCellAttributes:UICollectionViewLayoutAttributes 
       var lastCellAttributes:UICollectionViewLayoutAttributes 

       if (self.collectionView!.numberOfItemsInSection(section) > 0) { 
        firstCellAttributes = self.layoutAttributesForItemAtIndexPath(firstCellIndexPath)! 
        lastCellAttributes = self.layoutAttributesForItemAtIndexPath(lastCellIndexPath)! 
       } else { 
        firstCellAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: firstCellIndexPath)! 
        lastCellAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionFooter, atIndexPath: lastCellIndexPath)! 
       } 

       let headerHeight = CGRectGetHeight(layoutAttributes.frame) 
       var origin = layoutAttributes.frame.origin 

       origin.y = min(max(contentOffset.y, (CGRectGetMinY(firstCellAttributes.frame) - headerHeight)), (CGRectGetMaxY(lastCellAttributes.frame) - headerHeight)) 
       ; 

       layoutAttributes.zIndex = 1024; 
       layoutAttributes.frame = CGRect(origin: origin, size: layoutAttributes.frame.size) 

      } 
     } 
    } 

    return superAttributes 
} 
2

Swift 2.2 versione test sulla base di risposta di GregP. Il codice di Greg stava lanciando uno scomodo errore opzionale a lastCellIndexPath perché il numero della sezione è inizialmente zero.Così ho spostato il controllo numberOfItemsInSection> 0.

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

    let superAttributes:NSMutableArray = NSMutableArray(array: super.layoutAttributesForElementsInRect(rect)!) as NSMutableArray 

    let contentOffset = collectionView!.contentOffset 
    let missingSections = NSMutableIndexSet() 

    for layoutAttributes in superAttributes { 
     if (layoutAttributes.representedElementCategory == .Cell) { 
      if let _ = layoutAttributes.indexPath { 
       missingSections.addIndex(layoutAttributes.indexPath.section) 
      } 
     } 
    } 

    for layoutAttributes in superAttributes{ 
     if let representedElementKind = layoutAttributes.representedElementKind { 
      if representedElementKind == UICollectionElementKindSectionHeader { 
       if let indexPath = layoutAttributes.indexPath { 
        missingSections.removeIndex(indexPath.section) 
       } 
      } 
     } 
    } 

    missingSections.enumerateIndexesUsingBlock { idx, stop in 
     let indexPath = NSIndexPath(forItem: 0, inSection: idx) 
     let layoutAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: indexPath) 
     superAttributes.addObject(layoutAttributes!) 
    } 

    for la in superAttributes { 

     let layoutAttributes = la as! UICollectionViewLayoutAttributes; 

     if let representedElementKind = layoutAttributes.representedElementKind { 
      if representedElementKind == UICollectionElementKindSectionHeader { 
       let section = layoutAttributes.indexPath.section 
       let numberOfItemsInSection = collectionView!.numberOfItemsInSection(section) 

       if numberOfItemsInSection > 0{ 
        let firstCellIndexPath = NSIndexPath(forItem: 0, inSection: section) 
        let lastCellIndexPath = NSIndexPath(forItem: max(0, (numberOfItemsInSection - 1)), inSection: section) 

        var firstCellAttributes:UICollectionViewLayoutAttributes 
        var lastCellAttributes:UICollectionViewLayoutAttributes 

        firstCellAttributes = self.layoutAttributesForItemAtIndexPath(firstCellIndexPath)! 
        lastCellAttributes = self.layoutAttributesForItemAtIndexPath(lastCellIndexPath)! 

        let headerHeight = CGRectGetHeight(layoutAttributes.frame) 
        var origin = layoutAttributes.frame.origin 

        origin.y = min(max(contentOffset.y, (CGRectGetMinY(firstCellAttributes.frame) - headerHeight)), (CGRectGetMaxY(lastCellAttributes.frame) - headerHeight)); 

        layoutAttributes.zIndex = 1024; 
        layoutAttributes.frame = CGRect(origin: origin, size: layoutAttributes.frame.size) 
       } 
      } 
     } 
    } 

    return NSArray(array: superAttributes) as? [UICollectionViewLayoutAttributes] 
} 

override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { 
    return true 
} 
37

soluzione più semplice per iOS 9 + in quanto non ha bisogno di scrivere sottoclasse di UICollectionViewFlowLayout.

In viewDidLoad di viewController all'uso CollectionView seguente codice:

let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout // casting is required because UICollectionViewLayout doesn't offer header pin. Its feature of UICollectionViewFlowLayout 
layout?.sectionHeadersPinToVisibleBounds = true 

Si è accennato da @Antoine anche.

+0

Questo metodo funziona, ma mi chiedo perché il sectionheader viene sollevato quando incontra il footer – JayVDiyk

+0

Questo è fantastico! Soluzione migliore. – SeanRobinson159

+0

Sicuramente la soluzione più semplice e facile da usare. – lwdthe1

1

La versione di Swift 3 che cercava di evitare! Era dove aveva senso.

class StickyHeaderCollectionViewFlowLayout: UICollectionViewFlowLayout { 

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 
     guard var superAttributes = super.layoutAttributesForElements(in: rect), let collectionView = collectionView else { 
      return super.layoutAttributesForElements(in: rect) 
     } 

     let collectionViewTopY = collectionView.contentOffset.y + collectionView.contentInset.top 
     let contentOffset = CGPoint(x: 0, y: collectionViewTopY) 
     let missingSections = NSMutableIndexSet() 

     superAttributes.forEach { layoutAttributes in 
      if layoutAttributes.representedElementCategory == .cell && layoutAttributes.representedElementKind != UICollectionElementKindSectionHeader { 
       missingSections.add(layoutAttributes.indexPath.section) 
      } 
     } 

     missingSections.enumerate(using: { idx, stop in 
      let indexPath = IndexPath(item: 0, section: idx) 
      if let layoutAttributes = self.layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionHeader, at: indexPath) { 
       superAttributes.append(layoutAttributes) 
      } 
     }) 

     for layoutAttributes in superAttributes { 
      if let representedElementKind = layoutAttributes.representedElementKind { 
       if representedElementKind == UICollectionElementKindSectionHeader { 
        let section = layoutAttributes.indexPath.section 
        let numberOfItemsInSection = collectionView.numberOfItems(inSection: section) 

        let firstCellIndexPath = IndexPath(item: 0, section: section) 
        let lastCellIndexPath = IndexPath(item: max(0, (numberOfItemsInSection - 1)), section: section)     

        let cellAttributes:(first: UICollectionViewLayoutAttributes, last: UICollectionViewLayoutAttributes) = { 
         if (collectionView.numberOfItems(inSection: section) > 0) { 
          return (
           self.layoutAttributesForItem(at: firstCellIndexPath)!, 
           self.layoutAttributesForItem(at: lastCellIndexPath)!) 
         } else { 
          return (
           self.layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionHeader, at: firstCellIndexPath)!, 
           self.layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionFooter, at: lastCellIndexPath)!) 
         } 
        }() 

        let headerHeight = layoutAttributes.frame.height 
        var origin = layoutAttributes.frame.origin 
        // This line makes only one header visible fixed at the top 
//     origin.y = min(contentOffset.y, cellAttributes.last.frame.maxY - headerHeight) 
        // Uncomment this line for normal behaviour: 
        origin.y = min(max(contentOffset.y, cellAttributes.first.frame.minY - headerHeight), cellAttributes.last.frame.maxY - headerHeight) 

        layoutAttributes.zIndex = 1024 
        layoutAttributes.frame = CGRect(origin: origin, size: layoutAttributes.frame.size) 
       } 
      } 
     } 

     return superAttributes 
    } 

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { 
     return true 
    } 
} 
Problemi correlati