How can I change the scroll direction in UICollectionView?

70,881

Solution 1

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);
    }

Solution 2

Swift 4 and 4.2

if let layout = collectionViewObj.collectionViewLayout as? UICollectionViewFlowLayout {
        layout.scrollDirection = .vertical  // .horizontal
    }

Solution 3

Set the scrollDirection of the collection view's collectionViewLayout.

Docs are here.

Solution 4

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
    }

}

Solution 5

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
}
Share:
70,881

Related videos on Youtube

Kenny
Author by

Kenny

I studied Electronic Engineering in Glasgow from 1985, and have worked in electronics ever since. I'm self employed and enjoy work from a number of large and small clients across the UK. More and more of my work also includes firmware, Mac OS and iOS apps, but my firls love is electronics.

Updated on July 09, 2022

Comments

  • Kenny
    Kenny almost 2 years

    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?

  • Edward Dale
    Edward Dale over 10 years
    This only applies if you're using a UICollectionViewFlowLayout.
  • Dan Rosenstark
    Dan Rosenstark almost 8 years
    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 }
  • BTRUE
    BTRUE about 7 years
    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.