UICollectionView: One Row or Column

42,448

Solution 1

I am guessing you are using the built in Flow Layout. However, for your case, you should make a custom UICollectionView Layout. Make it subclass of UICollectionViewFlowLayout and add this code in the init method:

- (id)init {
    if ((self = [super init])) {
        self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        self.minimumLineSpacing = 10000.0f;
    }
    return self; 
}

The minimumLineSpacing is the key to making it have one line here.

I hope this helps!

Solution 2

I found that setting the minimumLineSpacing just made my scroll area really big and that setting the minimumInteritemSpacing=big accomplished keeping the items in one scrolling row or column, centered in the middle of the collectionview.

Solution 3

There isn't a real reason to subclass if you can trust the type cast.

((UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout).minimumLineSpacing = 1000.0f;

If you have your collectionView loaded from a nib you could also play around with the parameters in the Attributes and Size Inspectors.

Same goes for scroll direction.

Solution 4

When you init your UICollectionView pass the following UICollectionViewFlowLayout in the init parameter.

Note: You do not need to create a subclass of UICollectionViewFlowLayout

var collectionViewFlowControl = UICollectionViewFlowLayout()
collectionViewFlowControl.scrollDirection = UICollectionViewScrollDirection.Horizontal

For 0 px Cell Spacing:

collectionViewFlowControl.minimumInteritemSpacing = 0;
collectionViewFlowControl.minimumLineSpacing = 0;

collectionView = UICollectionView(frame: CGRectMake(0, 0, self.view.frame.size.width, 120), collectionViewLayout: collectionViewFlowControl)

Solution 5

In iOS 13, thanks to UICollectionViewCompositionalLayout, this is trivial, because you can specify the number of cells per column in a horizontal layout, or the number of cells per row in a vertical layout. Here's a simple example for a single horizontally scrolling, vertically centered row of cells:

func layout() -> UICollectionViewCompositionalLayout {
    let itemSize = NSCollectionLayoutSize(
        widthDimension: .fractionalWidth(1),
        heightDimension: .fractionalHeight(1))
    let item = NSCollectionLayoutItem(layoutSize: itemSize)
    let groupSize = NSCollectionLayoutSize(
        widthDimension: .absolute(75),
        heightDimension: .absolute(75))
    let group = NSCollectionLayoutGroup.vertical(
        layoutSize: groupSize, subitem: item, count: 1) // *
    group.edgeSpacing = NSCollectionLayoutEdgeSpacing(
        leading: nil, top: .flexible(0),
        trailing: nil, bottom: .flexible(0))
    let section = NSCollectionLayoutSection(group: group)
    section.interGroupSpacing = 65
    let config = UICollectionViewCompositionalLayoutConfiguration()
    config.scrollDirection = .horizontal
    let layout = UICollectionViewCompositionalLayout(
        section: section, configuration:config)
    return layout
}

Set your collection view's collectionViewLayout to the output of that function call and you're all set.

Share:
42,448
William T.
Author by

William T.

Updated on July 28, 2020

Comments

  • William T.
    William T. almost 4 years

    I want to use UICollectionView to display a horizontal scrollable list of thumbnails, however, I want this to be a single row. On another view, I'm displaying the thumbnails in a UICollectionView but this one scrolls vertically and it's in a single column.

    Currently, the way I'm doing this is by changing the size of the collection view to only be big enough for one item so it autowraps and works, but now I'm dealing with variable sized items so it doesn't work anymore.

    How do you make a UICollectionView display one row or column?

  • Chris Conover
    Chris Conover almost 10 years
    @giorashc, this is because it it laying out sideways, so a row would would be laid out vertically in this case. Hence setting a large value for minimumInterItemSpacing would require more space than the screen is tall, and it would break into multiple lines, horizontally.
  • Chris Conover
    Chris Conover almost 10 years
    do you know how this affects intrinsic content size? I am trying to implement a single row collection view as a slide up / pop over, and constrain it to its minimum intrinsic size for a single row. Thanks!
  • bitwit
    bitwit about 9 years
    In case anyone wonders why this isn't working for them and you set the class from inside a storyboard, try doing this inside of -(id)initWithCoder:(NSCoder *)aDecoder{} instead
  • Logan
    Logan almost 9 years
    +1 - One note is that you don't need to subclass for this (at least I didn't). In initializing my collection view, I did flow.minimumInterItemSpacing = CGFloat_Max;
  • Kamaldeep singh Bhatia
    Kamaldeep singh Bhatia almost 6 years
    I think self.scrollDirection = UICollectionViewScrollDirectionHorizontal; is the key to make it one line here. Can you please explain this one?
  • androidguy
    androidguy almost 4 years
    Except you should set minimumInteritemSpacing (or use minimumInteritemSpacingForSectionAt) regardless of whether it scrolls horizontally: as you quote, "For a vertically scrolling grid, this value represents the minimum spacing between items in the same row".
  • andesta.erfan
    andesta.erfan almost 4 years
    @androidguy I just copied apple documentation not mine!
  • Marcy
    Marcy almost 4 years
    Thank-you for this. For anyone needing to know how to plug this in, add the function to the view controller and set your collection view like this: yourCollection.collectionViewLayout = layout()
  • matt
    matt almost 4 years
    @Marcy Good addition, thanks. I'll just add a clarifying sentence too.
  • ChuckZHB
    ChuckZHB over 2 years
    Finally I found a worked solution in 2021. I think it gives a very big space value then there is no space for the second row/line. That is why it produces a single row/line. BTW, u don't need to subclass it, set it when you declare your layout UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; layout.minimumLineSpacing = CGFLOAT_MAX;
  • infiniteLoop
    infiniteLoop over 2 years
    Thanks a lot @matt, Marcy, the collectionview configurations always baffled me 🤨