48

I have a UICollectionView in my storyboard based iOS app. When the device is in the portrait orientation I'd like it to scroll vertically, and when it's in Landscaper I'd like it to scroll horizontally.

In UICollectionView I can see the scrollEnabled member, but I can see no way to set the scroll direction. Have I missed something?

Wayne Chen
  • 305
  • 2
  • 15
Kenny
  • 1,083
  • 2
  • 8
  • 23

6 Answers6

69
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];

Note too that it seems to be fine to call this in prepareForLayout in your flow layout...

@interface LayoutHorizontalThings : UICollectionViewFlowLayout
@end

@implementation LayoutHorizontalBooks
-(void)prepareLayout
    {
    [super prepareLayout];

    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

    self.minimumInteritemSpacing = 0;
    self.minimumLineSpacing = 0;
    self.itemSize = CGSizeMake(110,130);
    self.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
    }
Fattie
  • 27,874
  • 70
  • 431
  • 719
user3040186
  • 706
  • 6
  • 2
  • I'm seeing issues with this, where prepareLayout is intermittently not called early enough or called too late. The results are one of 3 things: 1) the horizontalSizeClass hasn't changed yet and scrolling direction is set incorrectly 2) scrollingDirection is set correctly but it's too late and doesn't take effect and 3) everything lines up properly and the scrolling direction actually takes effect as desired. It seems maybe Apple intends for scrolling direction to be managed in the view controller instead of the layout. – BTRUE Apr 17 '17 at 02:40
16

Swift 4 and 4.2

if let layout = collectionViewObj.collectionViewLayout as? UICollectionViewFlowLayout {
        layout.scrollDirection = .vertical  // .horizontal
    }
Gurjinder Singh
  • 9,221
  • 1
  • 66
  • 58
13

Set the scrollDirection of the collection view's collectionViewLayout.

Docs are here.

Mundi
  • 79,884
  • 17
  • 117
  • 140
  • 5
    This only applies if you're using a `UICollectionViewFlowLayout`. – Edward Dale Nov 02 '13 at 20:24
  • 2
    Thanks @Mundi, how do you know this stuff? Anyway, some code this for my own notes: `if let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout { flowLayout.scrollDirection = .Horizontal }` – Dan Rosenstark Aug 04 '16 at 16:36
9

You should try this:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{

  UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)[self.collectionView collectionViewLayout];

  if ((toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) || (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)){
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
  }
  else{
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;
  } 
}

In Swift:

override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {

    var layout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout

    if ((toInterfaceOrientation == UIInterfaceOrientation.LandscapeLeft) || (toInterfaceOrientation == UIInterfaceOrientation.LandscapeRight)){

        layout.scrollDirection = UICollectionViewScrollDirection.Vertical
    }
    else{
       layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
    }

}
Allan Scofield
  • 1,884
  • 18
  • 14
6

Kudos to Mundi and Dan Rosenstark for their answer, here's the swift 4.2 version.

if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
    flowLayout.scrollDirection = .horizontal
}
Travis M.
  • 10,930
  • 1
  • 56
  • 72
4

Do that in your Storyboard. From identity inspector and select the Scroll Direction and choose your direction.

enter image description here

Wide Angle Technology
  • 1,184
  • 1
  • 8
  • 28