Group Group Group Group Group Group Group Group Group Forums

Video Tutorial: Custom Collection View Layouts Part 4: DIY – Stretchy Headers

Learn how to implement a stretchy header similar to that of the DIY Skills for Kids app.

This is a companion discussion topic for the original entry at

Nice Tutorial Mic! I’m trying to implement same behavior, i have replaced the image view with map view. However i’m facing issue, when i’m scrolling down map view is taking time to load. Please advice how to resolve this. Thanks!

Thanks for the kind words.

How are you loading the map view? Perhaps you could load it in advance, offscreen?

Thanks Mic! I will try doing that. I’m trying to add some other feature to the Mapview, when scrolled down after maximum stretch map view will stretch to fit entire screen. Similar to link below, i tried to override Scrollview: DidScroll method, calculated offset and if it reaches maximum stretch changed the map view frame to fit entire screen. Unfortunately its not working. Please help.

override func scrollViewDidScroll(scrollView: UIScrollView) {
        let offset = collectionView?.contentOffset
        var presented = false
        if offset!.y < 0 {
            let deltaY = fabs(offset!.y)
            if deltaY > 190 && !presented {

                if let header = self.header {
                    presented = true
                    UIView.animateWithDuration(0.2, delay: 0, options: .CurveEaseInOut, animations: {
                        let layout = self.collectionViewLayout as! CustomCollectionFlowLayout
                        layout.headerReferenceSize = CGSize(width: self.view.bounds.width, height: self.view.bounds.height)
                        }, completion: nil)


Hi Mic, nice tutorial. I’m trying to apply the lesson to my project. The main difference is that I’m trying to apply what you’re teaching to an embedded CollectionView inside a regular view controller. The reason I’m doing this is because I want a header at the top of the screen and then a collection view that scrolls horizontally.

Most everything works. I can get the cards’ size and alpha to change. But the snap to card is not working. I put a print statement inside the targetContentOffset method and it never fires. I’m thinking the main reason is because as implemented in your lesson, it is an extension of the CollectionView controller, where in my project the main view controller is not a collection view controller.

For the life of me, I can’t figure this one out and was hoping you can help. Let me know if I’m not being clear in any way.

Hey. I got the same situation, because I wanted to use UIViewController with UICollectionView inside and not UICollectionViewController. My problem was because of life cycle of view controller. In few words, collectionView of UICollectionViewController is ready to use after creating UICollectionViewController, but UICollectionView is not ready. I mean we can use or change its frame after layoutDidLayoutSubviews. Which is happening after viewDidLoad. So finally, I decided to use UICollectionViewController as it provides more correct behavior.
What I’m struggling with is rotation handling. I want my layout to work in both landscape and portrait orientation. Does anyone have any suggestion which methods I need to override to achieve correct rotation support?

Very nice tutorial. It took me a long time to understand how to do this. Regarding the targetContentOffset part for snapping the cell in the center. I understand that the loop loops through all visible ‘cards’ within the screen, took me a while for that to click, check which are closest to the center and sort them on the closests one. Then take the first one and snap! It worked in my own example project, but I don’t understand it fully by far. I even have a CollectionViewLayout instead of Flow and everything works, thanks to an awesome tutorial here (Pinterest).
Array.sorted syntax is a bit new to me, but that is not the problem. After a long time analyzing I still don’t understand the math of abs($ - draggedOffset) < abs($ - draggedOffset) (I called it draggedOffset to help myself understand it better). I even drawn it in a graphics app to see the maths visually, it worked out but I don’t understand why.
Can you please explain the math a bit?

@skyrocketsw @micpringle Can you please help with this when you get a chance? Thank you - much appreciated! :]

Don’t know if you still read the comments but here’s a model that explains the math:

The blue distance value will be positive (because the offset+center is larger than the blue cell’s center.y) and the pink distance negative (as the offset+center is smaller than the pink cell’s center.y). That’s where the abs() function comes in, which disregards positivity or negativity of the value and just gives back the absolute value. Subsequently, the sorted() function sorts the values and places the smallest one up front - which is then picked by “.first”. This is done for ALL cells, not just the ones visible on screen.

Hope that helps.

@danielmey Thank you for sharing this - much appreciated!

Nice Tutorial Mic,
I have a problem when implementing the same methods in horizontal cards , the first card is sticked at loading time to end offset we created in the tutorial rather than the center of the first card, how to solve that please?