UICollectionView: One Row or Column

2019-01-17 06:22发布

问题:

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?

回答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!



回答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.



回答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.



回答4:

For Swift 3

let flowLayout = UICollectionViewFlowLayout()
flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.width/2-10, height: 190)
flowLayout.sectionInset = UIEdgeInsetsMake(0, 5, 0, 5)
flowLayout.scrollDirection = UICollectionViewScrollDirection.horizontal
flowLayout.minimumInteritemSpacing = 0.0
self.gCollectionView.collectionViewLayout = flowLayout


回答5:

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)


回答6:

 UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
 [layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];

 layout.minimumInteritemSpacing = 0;
 layout.minimumLineSpacing = 0;


 blendEffectCollectionView=[[UICollectionView alloc] initWithFrame:CGRectMake(0, 95, 320, 60) collectionViewLayout:layout];
 [blendEffectCollectionView setDataSource:self];
 [blendEffectCollectionView setDelegate:self];
 [blendEffectCollectionView registerClass:[BlendModeCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
 [blendEffectCollectionView setBackgroundColor:[UIColor clearColor]];

 [bottomActivityView addSubview:blendEffectCollectionView];


回答7:

I wanted one column, left aligned and the other answers didn't help me.

So here is my very simple solution for one column, left aligned:

class GCOneColumnLeftAlignedFlowLayout: UICollectionViewFlowLayout {
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let attributes = super.layoutAttributesForElements(in: rect)

        var y: CGFloat = sectionInset.top
        attributes?.forEach { layoutAttribute in
            layoutAttribute.frame.origin.x = sectionInset.left
            layoutAttribute.frame.origin.y = y
            y = y + layoutAttribute.frame.height + minimumLineSpacing
        }

        return attributes
    }
}

you also should set something like

estimatedItemSize = CGSize(width: 120, height: 40)

Don't forget to remove the line

minimumLineSpacing = big number

From the other solutions.

Hope this is helpful because it's a completely different approach compared to the other answers.