Custom UIScrollView paging with scrollViewWillEndDragging Custom UIScrollView paging with scrollViewWillEndDragging ios ios

Custom UIScrollView paging with scrollViewWillEndDragging


You can implement custom paging with this code:

- (float) pageWidth {    return ((UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout).itemSize.width +    ((UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout).minimumInteritemSpacing;}- (void) scrollViewWillBeginDragging:(UIScrollView *)scrollView {    CGFloat pageWidth = self.collectionView.frame.size.width + 10 /* Optional Photo app like gap between images. Or use [self pageWidth] in case if you want the next page be also visible */;    _currentPage = floor((self.collectionView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;    NSLog(@"Dragging - You are now on page %i", _currentPage);}- (void) scrollViewWillEndDragging:(UIScrollView*)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint*)targetContentOffset {    CGFloat pageWidth = self.collectionView.frame.size.width + 10; // [self pageWidth]    int newPage = _currentPage;    if (velocity.x == 0) { // slow dragging not lifting finger        newPage = floor((targetContentOffset->x - pageWidth / 2) / pageWidth) + 1;    }    else {        newPage = velocity.x > 0 ? _currentPage + 1 : _currentPage - 1;        if (newPage < 0)            newPage = 0;        if (newPage > self.collectionView.contentSize.width / pageWidth)            newPage = ceil(self.collectionView.contentSize.width / pageWidth) - 1.0;    }    NSLog(@"Dragging - You will be on %i page (from page %i)", newPage, _currentPage);    *targetContentOffset = CGPointMake(newPage * pageWidth, targetContentOffset->y);}

Of course you must set pagingEnabled = NO._currentPage is a class iVar.Thanks to http://www.mysamplecode.com/2012/12/ios-scrollview-example-with-paging.html for pointing the right way.


SWIFT 3

With a demo here https://github.com/damienromito/CollectionViewCustom

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {    let pageWidth = Float(itemWidth + itemSpacing)    let targetXContentOffset = Float(targetContentOffset.pointee.x)    let contentWidth = Float(collectionView!.contentSize.width  )    var newPage = Float(self.pageControl.currentPage)    if velocity.x == 0 {        newPage = floor( (targetXContentOffset - Float(pageWidth) / 2) / Float(pageWidth)) + 1.0    } else {        newPage = Float(velocity.x > 0 ? self.pageControl.currentPage + 1 : self.pageControl.currentPage - 1)        if newPage < 0 {            newPage = 0        }        if (newPage > contentWidth / pageWidth) {            newPage = ceil(contentWidth / pageWidth) - 1.0        }    }    let point = CGPoint (x: CGFloat(newPage * pageWidth), y: targetContentOffset.pointee.y)    targetContentOffset.pointee = point}


I was able to run a quick test and got this to correctly fire and make my object stop as desired. I did this using the following simple test:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{     targetContentOffset->x = scrollView.contentOffset.x - 10;    }

It seems that this method is likely not the issue in your code, but it is more likely that your 'goodOffsetX' is not correctly calculating a valid value to stop at.