NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

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.

1      

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

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

1      

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.

1      

@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

2      

Hacking with Swift is sponsored by MadMachine

SPONSORED Want to try Swift on microcontrollers? MadMachine provides ways to interact with the physical world in a Swift way. Join us and have fun!

Get it now

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.