UICollectionView: One Row or Column
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.
William T.
Updated on July 28, 2020Comments
-
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 aUICollectionView
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 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 almost 10 yearsdo 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 about 9 yearsIn 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 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 almost 6 yearsI think
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
is the key to make it one line here. Can you please explain this one? -
androidguy almost 4 yearsExcept you should set
minimumInteritemSpacing
(or useminimumInteritemSpacingForSectionAt
) 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 almost 4 years@androidguy I just copied apple documentation not mine!
-
Marcy almost 4 yearsThank-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 almost 4 years@Marcy Good addition, thanks. I'll just add a clarifying sentence too.
-
ChuckZHB over 2 yearsFinally 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 over 2 yearsThanks a lot @matt, Marcy, the collectionview configurations always baffled me 🤨