在 UICollectionView 中检测页面变化

Detect page change in UICollectionView

我试了一段时间才找到这个问题,但找不到这个问题的答案。 我的问题是我有一个 UICollectionView 并且滚动方向是 HorizontalPaging Enabled。我的问题是我想保持用户所在的当前页码的位置,所以我创建了一个 int 变量,现在每次用户向右或向左滑动时,我想将它加或减 1。我尝试使用 scrollView 的委托

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

但是当用户向右或向左滑动时,它被调用的次数与 UICollectionView 页面上的列数一样多,而且它不会让我知道用户是否去了下一页或上一页。

使用:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    CGFloat pageWidth = collectionView.frame.size.width;
    float currentPage = collectionView.contentOffset.x / pageWidth;

    if (0.0f != fmodf(currentPage, 1.0f))
    {
        pageControl.currentPage = currentPage + 1;
    }
    else
    {
        pageControl.currentPage = currentPage;
    }

    NSLog(@"Page Number : %ld", (long)pageControl.currentPage);
}

如果您没有使用任何 pageControl,那么 ceil(currentPage) 将是您当前的页码。

您可以像下面这样获取当前页面,索引将从0(total page - 1)

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
 {
    CGFloat pageWidth = scrollView.frame.size.width;
    int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    NSLog(@"Current page -> %d",page);
}

根据@Shankar BS 的回答,我在 Swit 中实现了这样的功能。请记住,CollectionViewDelegate 符合 ScrollViewDelegate:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    let pageWidth = scrollView.frame.size.width
    let page = Int(floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)
    print("page = \(page)")
}

Swift 2.2

 func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    let x = collectionView.contentOffset.x
    let w = collectionView.bounds.size.width
    let currentPage = Int(ceil(x/w))
    print("Current Page: \(currentPage)")
}

Swift 3 Xcode 8.2

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let x = scrollView.contentOffset.x
        let w = scrollView.bounds.size.width
        let currentPage = Int(ceil(x/w))
        // Do whatever with currentPage.
}

Xamarin.iOS:

您可以覆盖 UICollectionViewDelegateDecelerationEnded 方法或订阅 UICollectionViewDecelerationEnded 事件(自定义委托将在后台使用)。

public override void DecelerationEnded(UIScrollView scrollView)
{
    var x = scrollView.ContentOffset.X;
    var w = scrollView.Bounds.Size.Width;
    var currentPage = Math.Ceiling(x / w);

    // use currentPage here
}

SWIFT 5

例如,将此方法放在您的 ViewController 中,扩展名为 UICollectionViewDelegate、UICollectionViewDataSource

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let pageWidth = scrollView.frame.size.width
        let page = Int(floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)
        print("page = \(page)")
    }

当用户结束拖动时,您可以通过这种方式获取currentPage

Swift 5.6 测试成功!

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    let itemWidth = collectionView.frame.width // Get the itemWidth. In my case every cell was the same width as the collectionView itself
    let contentOffset = targetContentOffset.pointee.x

    let targetItem = lround(Double(contentOffset/itemWidth))
    let targetIndex = targetItem % YOUR_ARRAY.count // numberOfItems which shows in the collection view
    print(targetIndex)
}