Search code examples
iosipaduicollectionview

UICollectionView horizontal paging with 3 items


I need to show 3 items in a UICollectionView, with paging enabled like this

enter image description here

but I am getting like this enter image description here

I have made custom flow, plus paging is enabled but not able to get what i need. How can i achieve this or which delegate should i look into, or direct me to some link from where i can get help for this scenario.

- (void)awakeFromNib
{
    self.itemSize = CGSizeMake(480, 626);
    self.minimumInteritemSpacing = 112;
    self.minimumLineSpacing = 112;
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    self.sectionInset = UIEdgeInsetsMake(0, 272, 0, 272);
}

Solution

  • Edit: Demo link: https://github.com/raheelsadiq/UICollectionView-horizontal-paging-with-3-items

    After a lot searching I did it, find the next point to scroll to and disable the paging. In scrollviewWillEndDragging scroll to next cell x.

    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
    {
    
        float pageWidth = 480 + 50; // width + space
    
        float currentOffset = scrollView.contentOffset.x;
        float targetOffset = targetContentOffset->x;
        float newTargetOffset = 0;
    
        if (targetOffset > currentOffset)
            newTargetOffset = ceilf(currentOffset / pageWidth) * pageWidth;
        else
            newTargetOffset = floorf(currentOffset / pageWidth) * pageWidth;
    
        if (newTargetOffset < 0)
            newTargetOffset = 0;
        else if (newTargetOffset > scrollView.contentSize.width)
            newTargetOffset = scrollView.contentSize.width;
    
        targetContentOffset->x = currentOffset;
        [scrollView setContentOffset:CGPointMake(newTargetOffset, scrollView.contentOffset.y) animated:YES];
    }
    

    I also had to make the left and right small and center large, so i did it with transform. The issue was finding the index, so that was very difficult to find.

    For transform left and right in this same method use the newTargetOffset

    int index = newTargetOffset / pageWidth;
    
    if (index == 0) { // If first index 
        UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index  inSection:0]];
    
        [UIView animateWithDuration:ANIMATION_SPEED animations:^{
            cell.transform = CGAffineTransformIdentity;
        }];
        cell = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index + 1  inSection:0]];
        [UIView animateWithDuration:ANIMATION_SPEED animations:^{
            cell.transform = TRANSFORM_CELL_VALUE;
        }];
    }else{
        UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]];
        [UIView animateWithDuration:ANIMATION_SPEED animations:^{
            cell.transform = CGAffineTransformIdentity;
        }];
    
        index --; // left
        cell = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]];
        [UIView animateWithDuration:ANIMATION_SPEED animations:^{
            cell.transform = TRANSFORM_CELL_VALUE;
        }];
    
        index ++;
        index ++; // right
        cell = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]];
        [UIView animateWithDuration:ANIMATION_SPEED animations:^{
            cell.transform = TRANSFORM_CELL_VALUE;
        }];
    }
    

    And in cellForRowAtIndex add

    if (indexPath.row == 0 && isfirstTimeTransform) { // make a bool and set YES initially, this check will prevent fist load transform
        isfirstTimeTransform = NO;
    }else{
        cell.transform = TRANSFORM_CELL_VALUE; // the new cell will always be transform and without animation 
    }
    

    Add these two macros too or as u wish to handle both

    #define TRANSFORM_CELL_VALUE CGAffineTransformMakeScale(0.8, 0.8)
    #define ANIMATION_SPEED 0.2
    

    The end result is

    enter image description here