Search code examples
iosuiscrollviewuicollectionview

UICollectionView Horizontal Paging not centered


I have a horizontal scrolling collectionView with each cell the size of the view. When I page through the collectionView it doesn't page by cell. The cells aren't in the center of the screen. I've tried a bunch of things to try to fix it and haven't had any luck. Here's a video of the problem: https://www.youtube.com/watch?v=tXsxWelk16w Any ideas?


Solution

  • Remove spaces between items. For horizontal scrolling collection view set minimum line spacing to 0. You can do this with interface builder or with method of UICollectionViewDelegateFlowLayout protocol:

    - (CGFloat)collectionView:(UICollectionView *)collectionView 
                       layout:(UICollectionViewLayout *)collectionViewLayout 
            minimumLineSpacingForSectionAtIndex:(NSInteger)section {
        return 0;    
    }
    

    enter image description here

    Another way is making your cell's width less than collectionView's width for a value of horizontal space between items. Then add section insets with left and right insets that equal a half of horizontal space between items. For example, your minimum line spacing is 10:

    - (CGFloat)collectionView:(UICollectionView *)collectionView
                       layout:(UICollectionViewLayout *)collectionViewLayout
            minimumLineSpacingForSectionAtIndex:(NSInteger)section {
        return 10;
    }
    
    - (CGSize)collectionView:(UICollectionView *)collectionView 
                      layout:(UICollectionViewLayout *)collectionViewLayout 
      sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
        return CGSizeMake(collectionView.frame.size.width - 10, collectionView.frame.size.height);
    }
    
    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView 
                            layout:(UICollectionViewLayout *)collectionViewLayout 
            insetForSectionAtIndex:(NSInteger)section {
        return UIEdgeInsetsMake(0, 5, 0, 5);
    }
    

    enter image description here

    And third way: manipulate collectionView scroll in scrollViewDidEndDecelerating: method:

    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
        if (scrollView == self.collectionView) {
            CGPoint currentCellOffset = self.collectionView.contentOffset;
            currentCellOffset.x += self.collectionView.frame.size.width / 2;
            NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:currentCellOffset];
            [self.collectionView scrollToItemAtIndexPath:indexPath
                                        atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
                                                animated:YES];
        }
    }
    

    enter image description here