Search code examples
iosf#xamarin.iosuicollectionviewuicollectionviewlayout

Sticky UICollectionView Header F#


I have a UICollectionViewController with the following layout:

enter image description here

So we have a CollectionView and a Header containing a Reusable View.

I implement the following method for the reusable view:

override x.GetViewForSupplementaryElement(collectionView : UICollectionView, elementKind : NSString, indexPath : NSIndexPath) =
    let headerView = (collectionView.DequeueReusableSupplementaryView(elementKind,new NSString("HeaderView"),indexPath))
    headerView

My only problem is, I do not want the header to scroll along with the UICollectionView, I want it to stay in a fixed position at all times on top of the UICollectionView. How can I achieve this?


Solution

  • This can be done using the following code:

    let layout = x.CollectionView.CollectionViewLayout :?> UICollectionViewFlowLayout
    layout.SectionHeadersPinToVisibleBounds <- true
    

    Adapted from UICollectionView sticky header in swift

    In order to eliminate white space on top of collectionView do the following:

    x.AutomaticallyAdjustsScrollViewInsets <- false
    x.CollectionView.ContentInset <- UIEdgeInsets(Conversions.nfloat(-44),Conversions.nfloat(0), Conversions.nfloat(0), Conversions.nfloat(0))
    

    Note that the value of -44 is used for iPhone X specifically, and might differ for other models.

    Conversions is used to convert to nfloat. This is the code that does this conversion:

    let inline nfloat (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> nfloat) x)
    

    Finally, if you wish to eliminate vertical bouncing on top of the UICollectionView add the following code to your UICollectionViewController :

    override x.Scrolled(scrollView : UIScrollView) = 
        if (scrollView.ContentOffset.Y < Conversions.nfloat(0)) then 
            scrollView.ContentOffset <- CGPoint(scrollView.ContentOffset.X, Conversions.nfloat(0))