UICollectionView with Paging Enable

2019-03-29 12:33发布

问题:

I have to create Grid view like Appstore iOS app. I want to do this with UICollectionView paging. I have also implemented the code but not able to scroll like that.

What I want to do is there will one image in Center and at both sides(left and right), it should show some portion of previous and next image. I have set Frame for UICollectionView is 320*320. cell size is 290*320.(cell min spacing is 10)1

Below are two links which depicts my requirement. Thanks in advance.

(This is what I want) 2

回答1:

Have you tried setting the scroll direction of your UICollectionViewFlowLayout to horizontal?

[yourFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];

You'll need to enable paging on your collection view like so:

[yourCollectionView setPagingEnabled:YES];



回答2:

I took shtefane's answer and improved on it. Enter your own cellWidth and cellPadding values.

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset
{
    CGFloat cellWidth = self.cellWidth;
    CGFloat cellPadding = 9;

    NSInteger page = (scrollView.contentOffset.x - cellWidth / 2) / (cellWidth + cellPadding) + 1;

    if (velocity.x > 0) page++;
    if (velocity.x < 0) page--;
    page = MAX(page,0);

    CGFloat newOffset = page * (cellWidth + cellPadding);
    targetContentOffset->x = newOffset;
}


回答3:

If you use pagining in collectionView it will scroll by one page Not one cell. You can disable pagining and implement ScrollViewDelegate

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
 {
     CGFloat pageW = 300;
    int page = scrollView.contentOffset.x / pageW;

    CGFloat newOffset =(page + ((velocity.x > 0)? 1 : -1)) * (pageW - 20);
    CGPoint target = CGPointMake(newOffset, 0);
    targetContentOffset = &target;
    NSLog(@"end Drag at %f /%i /%f",scrollView.contentOffset.x, page, velocity.x);

 }

Only one different from standart paging: If you drag fast Collection will scroll more than one cell. And don't forget to add UIScrollViewDelegate



回答4:

Here's a working swift4 version of Rickster answer:

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {

    let cellWidth = 174 as CGFloat
    let cellPadding = 10 as CGFloat

    var page = (scrollView.contentOffset.x - cellWidth / 2) / (cellWidth + cellPadding) + 1

    if (velocity.x > 0) { page += 1 }
    if (velocity.x < 0) { page -= 1 }

    page = max(page,0)

    targetContentOffset.pointee.x = page * (cellWidth + cellPadding)
}


回答5:

Ref to Rickster's answer and I rewrite with Swift 4:

/* paging */
extension AlbumViewController {

    /* In case the user scrolls for a long swipe, the scroll view should animate to the nearest page when the scrollview decelerated. */
    override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        scrollToPage(scrollView, withVelocity: CGPoint(x:0, y:0))
    }

    override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        scrollToPage(scrollView, withVelocity: velocity)
    }

    func scrollToPage(_ scrollView: UIScrollView, withVelocity velocity: CGPoint) {
        let cellWidth: CGFloat = cellSize
        let cellPadding: CGFloat = 10

        var page: Int = Int((scrollView.contentOffset.x - cellWidth / 2) / (cellWidth + cellPadding) + 1)
        if velocity.x > 0 {
            page += 1
        }
        if velocity.x < 0 {
            page -= 1
        }
        page = max(page, 0)
        let newOffset: CGFloat = CGFloat(page) * (cellWidth + cellPadding)

        scrollView.setContentOffset(CGPoint(x:newOffset, y:0), animated: true)
    }
}


回答6:

Just use collectionView.isPagingEnabled = true;