20

I made a UICollectionView with a vertical scroll.

The width of the cell is more than than the screen width, so I created a customFlowLayout based on UICollectionViewFlow layout returning the right calculated content size.

However, this doesn't work. When the width of the cell is less than the screen width it works. Does it mean that we can't have width more than than screen width in vertical scroll?

It is the same for horizontal scroll, but then the height of the CollectionView is limited to screen height.

Is there any way to make it work?

Matt Fenwick
  • 44,546
  • 19
  • 115
  • 184
last-Programmer
  • 775
  • 3
  • 8
  • 17
  • 1
    I had to revisit it recently. I created a demo project hosted here: https://github.com/izotx/ScrollableCollectionView It's using collection view embedded in a scroll view to scroll content in both ways. Hopefully you will find it useful. – Janusz Chudzynski Apr 12 '16 at 15:03

5 Answers5

14

As others have already said, the UICollectionView can only scroll one direction using a flow layout. However you can accomplish this very easily without creating a custom layout or using a third party library.

When you lay your view out in story board, you can put your UICollectionView embedded in a UIScrollView. Have the scrollview set up to scroll horizontally and the UICollectionView to scroll Vertically. Then set the UICollectionView.delaysContentTouchesto true so touches will pass through to the UIScrollView and not think you are trying to scroll the collectionview.

When you set up the UICollectionView, set it's size and the size of the cells to be what you actually want them to be (Wider than the actual screen) and lay them out accordingly.

Now in the containing UIViewController put this code in the view lifecycle

    - (void)viewDidLayoutSubviews {
        self.myScrollView.contentSize = self.myCollectionView.frame.size;
    }

That's literally all you have to do to accomplish what you are describing. Now your scrollview should allow you to scroll horizontally to view your entire cell and your collectionView should scroll vertically through your cells.

Happy programming.

stonedauwg
  • 1,128
  • 10
  • 29
johnrechd
  • 1,723
  • 17
  • 25
  • 10
    This worked for me, but beware: this layout will force the CollectionView to generate all of its cells at once, so this solution is impractical with larger numbers of cells. I ended up needing to find a different solution (http://stackoverflow.com/q/15549233/1418688), because my CollectionView was very large. – Nerrolken Sep 03 '14 at 02:41
  • 1
    @AlexanderWinn, thanks for the feedback. The linked solution is great. In this specific question, you actually shouldn't need to load more cells than you need. I use this in a continuously scrollable calendar week (vertical hours). So it has potentially infinite cells and I load them as needed. The linked solution is for a collectionview with rows and columns where you need to scroll both directions (in a sort of zoomed state). This question is more specifically for a collection view with a single row, where each individual cell is larger than the viewable screen. Good clarification though. – johnrechd Sep 08 '14 at 22:59
  • 1
    Where should i add the Delay Content Touches? – johnny Jun 07 '17 at 17:10
  • 1
    @johnny - probably in viewDidLoad or in the storyboard or xib if you are using one. – johnrechd Jun 11 '17 at 22:23
  • @Nerrolken curious, why does it force the CV to load all cells at once? – stonedauwg Aug 23 '18 at 17:45
0

I'm not sure I've understood your problem.

But if you have made a custom layout, make sure you have implemented :

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;

and that your layout attributes frame and size are set with correct values for your "large cell" index path.

Also make sure you have implemented :

- (CGSize) collectionViewContentSize;

This method returns the contentSize of the collection View. If contentSize.width > youAppFrame.width you should have horizontal scrolling. Same for height and vertical scrolling.

Also make sure your collectionView allows scrolling and that your layout is prepared correctly using :

- (void)prepareLayout

By the way, for your layout have you overloaded UICollectionViewLayout or UICollectionViewFlowLayout ?

  • I am subclassing UICollectionViewFlowLayout... i have specified the collectionViewContentSize. in the preparelayout i am setting the itemsize [self setItemSize:CGSizeMake(10.0f*200.0f, 30)]; my requirement is, the cell width is above the screen width and has rows more than screen height. i dont know how to achieve this using uicollectionview... – last-Programmer Dec 22 '12 at 20:48
0

Before you can do that you MUST use a different type of layout. The flow layout represents its items as a list and it spans these items in cells based on the available width. If you want to have both horizontal and vertical scrolling you need to somehow specify the number of columns for your grid. the FlowLayout doesn't have that. A simple sollution is to make a subclass of UICollectionViewLayout and override collectionViewContentSize to make it retun a width = to the added sum of the cells widths of one row (this is where knowing how many collumns you want is necessary), plus any additional spacing between them. This will work fine if your cells have the same size per column, similar to a grid.

Radu Simionescu
  • 3,699
  • 28
  • 33
0

Xcode 11+, Swift 5.

I solved my issue, I prepared video and code

phi
  • 10,350
  • 6
  • 50
  • 82
Ahmed Abdallah
  • 2,081
  • 1
  • 16
  • 28
0

You should embed a UITableView into a UIScrollView. ScrollView and TableView will have the same height but different widths. This way UITableView will scroll vertical and UIScrollView will scroll horizontal.