Shadowman Shadowman - 1 year ago 333
iOS Question

UICollectionView - Horizontal scroll, horizontal layout?

I have a UIScrollView that lays out a grid of icons. If you were to imagine the layout for the iOS Springboard, you'd be pretty close to correct. It has a horizontal, paged scroll (just like Springboard). However, it appears that the layout is not quite right. It appears as though it is laying out the items from top to bottom. As a result, my last column only has 2 rows in it, due to the number of items to be displayed. I'd rather have my last row on the last page have 2 items, like you would see in the Springboard.

How can this be accomplished with UICollectionView and its related classes? Do I have to write a custom UICollectionViewFlowLayout?

Answer Source

1st approach

What about using UIPageViewController with an array of UICollectionViewControllers? You'd have to fetch proper number of items in each UICollectionViewController, but it shouldn't be hard. You'd get exactly the same look as the Springboard has.

2nd approach

I've thought about this and in my opinion you have to set:

self.collectionView.pagingEnabled = YES;

and create your own collection view layout by subclassing UICollectionViewLayout. From the custom layout object you can access self.collectionView, so you'll know what is the size of the collection view's frame, numberOfSections and numberOfItemsInSection:. With that information you can calculate cells' frames (in prepareLayout) and collectionViewContentSize. Here're some articles about creating custom layouts:

3rd approach

You can do this (or an approximation of it) without creating the custom layout. Add UIScrollView in the blank view, set paging enabled in it. In the scroll view add the a collection view. Then add to it a width constraint, check in code how many items you have and set its constant to the correct value, e.g. (self.view.frame.size.width * numOfScreens). Here's how it looks (numbers on cells show the indexPath.row): If you're not satisfied with the way cells are ordered, then I'm afraid you'd have to go with 1. or 2.