NEW: Start my new Ultimate Portfolio App course with a free Hacking with Swift+ trial! >>

Custom item frames in new UICollectionViews

Forums > iOS

How can I give a (different) CGFame to each individual cell in a new UICollectionView (2019+) in order to position and size them in a horizontally scrolling group / section?

Example: I want the cells to represent events on a horizontally scrolling timeline, the timeline runs linearly from x=0 to x=100, then I want to position a cell at x=3 with a width of 7, another cell at x=20 with w=10, another at x=46 with w=21, etc... some might even overlap.

   

Not sure I understand what you want, but this tutorial might help you:

https://www.raywenderlich.com/8549-self-sizing-table-view-cells

   

Thanks @guseulalio! I am more or less familiar with the method proposed in that tutorial. I'm more interested in Collection Views though. Specifically with the new classes introduced in 2019 for building Compositional Layouts.

Based on Paul's video on new Collection Views I'm trying to rework the createSection() function in order to provide a frame for each specific cell, therefore I will not be using any of the standard layouts (like Flow Layout). In particular I'm intrigued about the usage of NSCollectionLayoutGroup

    func createSection() -> NSCollectionLayoutSection {
        let itemSize = NSCollectionLayoutSize(widthDimension: .absolute(300), heightDimension: .absolute(300))
        let layoutItem = NSCollectionLayoutItem(layoutSize: itemSize)
        layoutItem.contentInsets = NSDirectionalEdgeInsets(top: 40, leading: 40, bottom: 40, trailing: 40)

        let layoutGroup = NSCollectionLayoutGroup.horizontal(layoutSize: itemSize, subitems: [layoutItem])

        let layoutSection = NSCollectionLayoutSection(group: layoutGroup)
        layoutSection.orthogonalScrollingBehavior = .continuous      
        return layoutSection
    }

Apple's documentation says I can choose to use a .custom instead of .horizontal layout for NSCollectionLayoutGroup. This would allow me to set a frame for each specific cell. But how should that be implemented? I believe apple published sample code for all other options except .custom.

   

@Juan-GH Have you found anything on using NSCollectionLayoutGroup.custom? I also am trying to do this myself to make a timeline where my cells are seperated based on amount of time passing between them. Let me share what I believe to be true.

As you may or may not know, you have to fill out a NSCollectionLayoutGroupCustomItemProvider closure for your group. This closure gives you the enviroment as parameters but no reference to the indexpath or anything regarding which cells you are providing.

This leads me to believe that NSCollectionLayoutGroup's, even custom ones, do not want to use any information in your data model. They will not lay themselves out differently because they are laying out some cells instead of others. For instance, here is my attempt

        let mainGroup = NSCollectionLayoutGroup.custom(layoutSize: mainGroupSize) { env in
            var frame = CGRect(x: 0,y: 0,width: self.cellWidth,height: self.collectionView.frame.height)
            let firstDay = self.days[0].date      // This probably doesn't work
            var items = [NSCollectionLayoutGroupCustomItem(frame: frame)]
            for day in self.days {
                let dayDiff = day.date.days(from: firstDay)
                frame.origin.x = self.cellWidth * CGFloat(dayDiff)
                items.append(NSCollectionLayoutGroupCustomItem(frame: frame))
            }
            return items
        }

As you can see this loops through my classes self.days and writes out all of the items based on their time difference from the start date. However you can see that its writing out all of the days in every single group. That means if this was in a nested group, it would just replicate the data across every group. I don't know of a way to "pickup where you left off". So yeah, I don't think this is how you do this. Its possible that I am confusing the concept of a group with a section.

And yeah there is basically no information on NSCollectionLayoutGroup.custom online. I would suggest googling that or NSCollectionLayoutGroupCustomItemProvider

   

Hacking with Swift is sponsored by Essential Developer

SPONSORED From January 26th to 31st you can join a FREE crash course for iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a senior developer!

Save your spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.