3

pretty new to CollectionView so hope to have a direction here.

I have a CollectionView with an header enabled. All works fine but I want the HeaderView stay still while scrolling the main section.

Question:

  • Is that possible in iOS given a collectionview? Or I have to create a dedicated still view for the header?

I set the below in the UICollectionViewFlowLayout

    if let layout: UICollectionViewFlowLayout = self.collectionViewLayout as? UICollectionViewFlowLayout {
        layout.scrollDirection = .vertical
        layout.sectionHeadersPinToVisibleBounds = true
    }

which makes the header behave as below:

  • When scrolling down the main collection, the header goes up until it's lower margin reaches the top of the screen, then bunches in the middle of the sceen
  • When going up the header follows the main collection and become hided

I am pretty sure I am not the only one which has had this issue. Maybe I am doing something wrong here?

czane
  • 392
  • 1
  • 6
  • 18

1 Answers1

1
layout.sectionHeadersPinToVisibleBounds = true

that makes your header:

  • stick to the cells, when you scroll down
  • begin to hide after bottom of cells reaches bottom of the header

I see that you want the header to be still at all times. Of course, as you said, you could add a UIView on top of the collectionView, which would do the job. A different solution may be this:

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "header", for: indexPath)
        headerContainer.backgroundColor = .yellow
        headerContainer.frame = header.frame
        header.layer.masksToBounds = false // that's important
        header.addSubview(self.headerContainer)
        return header
    }

So basically, we're adding a subview inside our header (header needs to be transparent then). Now, we're using the fact that UICollectionView is scrollable:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let offset = scrollView.contentOffset.y
        if offset < 0 {
            headerContainer.transform = CGAffineTransform(translationX: 0, y: offset)
        }
    }

So if we are scrolling down by offset value, we transform the container by adding offset value to its Y position.

Unfortunately, I haven't come up with the case of scrolling up (it still begins to hide after some time) - I guess it's doable.

I based on this topic: TableView header bouncing

I think I'd rather make a UIView outside of UICollectionView anyway.

Tieme
  • 62,602
  • 20
  • 102
  • 156
Kowboj
  • 351
  • 2
  • 14
  • Thanks for that. How can I add a top margin on the main collectionview without adding it to the header? If I use override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { that will be added to the entire collectionview. – czane Apr 19 '18 at 12:22
  • Can you explain your question in more details? Do you need a space between header and the first cell? If so - two options - add blank UIView to header under headerContainer OR make the first cell wide as screen and empty (if indexPath.row == 0 { //cell.width = ... background = white hide buttons}) – Kowboj Apr 19 '18 at 12:55
  • Sure. I need to put a tabBar at the top of the collectionView just after the headerView. That way I can change the collectionView onClick of the tab. – czane Apr 19 '18 at 14:51