16

I know the documented advice is to use UICollectionViewFlowLayout if you are doing anything "like a grid or a line-based breaking layout". However, I am not sure this is true for my case.

I want a grid but do not want a line-breaking layout. Items should be laid out infinitely both horizontally and vertically without ever stacking. Essentially, a giant chessboard that scrolls horizontally or vertically if content goes beyond the frame.

To subclass UICollectionViewFlowLayout I would have to:

  1. Override prepareLayout to stop the layout from wrapping items. This seems like a lot of work.
  2. Override collectionViewContentSize.

Apple says they have done "lots of hard work" in crafting UICollectionViewFlowLayout, so I should leverage it if I can. But if I have to override prepareLayout to turn off line-breaking, I suspect that I am throwing away a large part of their work. Of their work that is left, I probably will not use most of it anyway (for example, minimumLineSpacingForSectionAtIndex).

Because the layout I want is so simple, I suspect that I should subclass UICollectionViewLayout instead, because:

  1. I will have a simpler and cleaner implementation with everything in one layout class instead of spread between a subclass and a delegate.
  2. I don't think it will be that much harder than subclassing UICollectionViewFlowLayout because I have to override prepareLayout in both cases, and I suspect that is where all the hard work will be.
  3. I'll be in a better position to tweak other UICollectionViewLayoutAttributes in custom ways than trying to add another kludge on top of a UICollectionViewFlowLayout subclass.

Is my conclusion correct?

Jeff
  • 3,829
  • 1
  • 31
  • 49

2 Answers2

12

UICollectionViewFlowLayout can't support two directions anyway, it scrolls along one axis only, either horizontally or vertically. So you have to subclass UICollectionViewLayout not UICollectionViewFlowLayout.

Then you have to override prepareForLayout, layoutsAttributesForElementsInRect methods as you said correctly..

Jirune
  • 2,310
  • 3
  • 21
  • 19
  • I think the scrollDirection property of UICollectionViewFlowLayout is implemented by never letting the contentSize in one direction get bigger than the frame. This would force the UICollectionView, which is a subclass of UIScrollView, to only scroll in one direction. So I think if I overrode prepareLayout and collectionViewContentSize of UICollectionViewFlowLayout, I could probably make it scroll in both directions, although this would make scrollDirection property useless. But thank you for the advice to subclass UICollectionViewLayout; it seems like that is the cleanest solution. – Jeff Jan 24 '13 at 03:38
  • This is incorrect, having created https://github.com/pavankataria/SwiftDataTables you can scroll in both directions if you subclass `UICollectionViewFlowLayout` – Pavan Oct 12 '17 at 11:16
0

The layout you describe (items arranged in an indefinitely long horizontal line and sections arranged in an indefinitely long vertical line) resembles the "featured" section of the App Store :)

I have been meaning to use a similar concept in some of my apps too, and I think the trick here is that it's not handled by a single UICollectionView. It appears that what you are looking for can be achieved by using a UITableView as a base, and have each section of your content take up a single cell in the table. That is, each UITableViewCell would contain a UICollectionView with horizontal scrolling.

The key limitation of UICollectionView that is sometimes not trivial to understand is that it is, after all, a single scrollView. You can override some functionality to enable scrolling in both directions, but if you want some content to scroll one way, and some content to scroll another way, you would have to create nested scrollViews.

SaltyNuts
  • 5,068
  • 8
  • 48
  • 80
  • Actually, that is not what I wanted. I am sorry for my lack of clarity. The App Store Featured section has independent scrolling for each section. Imagine a giant chess board that is larger than the screen. That is visually what I was after. I girded my loins back then and subclassed UICollectionViewLayout, and it was not difficult to implement, and I got exactly what I wanted instead of trying to kluge it with the FlowLayout. If I recall correctly, implementing the subclass was easier than writing the Stackoverflow question. – Jeff Jul 28 '14 at 05:38