David Henry
David Henry

Reputation: 3062

Dynamic Cell Width In Compositional Layout

I am looking to achieve the below illustration. Essentially it is a horizontal 'section' within a UICompositionalLayout where the cells size to the text.

illustration of horizontal section

The issue I am having is that if the cell doesn't fit onto the screen it will offset to the next screen page.

Here is my code:

fileprivate func createNavigationButtonSection(using section: HomeSection) -> NSCollectionLayoutSection {
        let estimatedHeight: CGFloat = 40
        let estimatedWidth: CGFloat = 100
        let itemSize = NSCollectionLayoutSize(widthDimension: .estimated(estimatedWidth),
                                              heightDimension: .estimated(estimatedHeight))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: nil,
                                                         top: nil,
                                                         trailing: .fixed(8),
                                                         bottom: nil)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                               heightDimension: .estimated(estimatedHeight))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                       subitems: [item])
        let section = NSCollectionLayoutSection(group: group)
        section.orthogonalScrollingBehavior = .continuous
        section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 0)
        return section
    } 

This is the effect it is giving where it pushes the last cell

gif illustration

UPDATE

fileprivate var navigationButtons: [NavigationButton] = [
        NavigationButton(image: UIImage(named: "heart"), title: "Saved", query: "item_saved"),
        NavigationButton(image: UIImage(named: "grid"), title: "Categories", query: "item_categories"),
        NavigationButton(image: UIImage(named: "deal"), title: "Deals", query: "item_deals"),
        NavigationButton(image: UIImage(named: "clock"), title: "Latest", query: "item_latest"),
    ]

fileprivate var sections = [HomeSection]()

In ViewDidLoad:

sections = [HomeSection(title: nil, subtitle: nil, section_type: "navigationButtons", item: navigationButtons)]

Upvotes: 2

Views: 2393

Answers (2)

Nalin Porwal
Nalin Porwal

Reputation: 11

You have to just add interGroupSpacing in section and Put Same NSCollectionLayoutSize to item and group

 fileprivate func createNavigationButtonSection(using section: HomeSection) -> NSCollectionLayoutSection {
        let estimatedHeight: CGFloat = 40
        let estimatedWidth: CGFloat = 100
        let size = NSCollectionLayoutSize(widthDimension: .estimated(estimatedWidth),
                                              heightDimension: .estimated(estimatedHeight))
        let item = NSCollectionLayoutItem(layoutSize: size)
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: size,
                                                       subitems: [item])
        let section = NSCollectionLayoutSection(group: group)
        section.interGroupSpacing = 8
        section.orthogonalScrollingBehavior = .continuous
        section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 0)
        return section
    }

Upvotes: 0

Owen
Owen

Reputation: 899

The following should work and provide the outcome you're after. We'll use the itemSize for the group size and to make sure the items are separated we'll add some interGroupSpacing to the section to spread the groups out.

let group = NSCollectionLayoutGroup.horizontal(layoutSize: itemSize, subitems: [item])
...
section.interGroupSpacing = 20

Upvotes: 4

Related Questions