简体   繁体   English

检测 UICollectionView 中的页面变化

[英]Detect page change in UICollectionView

I tried finding this question for a while but could not find this problem's answer.我试图找到这个问题一段时间,但找不到这个问题的答案。 My problem is that i have a UICollectionView and the Scroll Direction is Horizontal with Paging Enabled .我的问题是我有一个UICollectionView并且滚动方向是Horizontal的,并且Paging Enabled My problem is that i want to keep the tack of the current page number on which the user is, so i created an int variable and now want to add or subtract it by 1 each time the user swipes right or left.我的问题是我想保留用户所在的当前页码,所以我创建了一个int变量,现在希望每次用户向右或向左滑动时将其加减 1。 I tried using scrollView 's delegate我尝试使用scrollView的委托

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

but when the user swipes right or left, it is called as many number of the times as the number of columns on a page in the UICollectionView plus it wont let me know that whether the user went to the next page or the previous one.但是当用户向右或向左滑动时,它被调用的次数与UICollectionView中页面上的列数一样多,而且它不会让我知道用户是转到下一页还是上一页。

Swift 3 Xcode 8.2斯威夫特 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.
}

Use :利用 :

- (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);
}

And if you are not using any pageControl, then ceil(currentPage) will be your current page number.如果您没有使用任何 pageControl,那么ceil(currentPage)将是您当前的页码。

Based on @Shankar BS 's answer I've implemented it like this in Swit.基于@Shankar BS 的回答,我在 Swit 中实现了这样的功能。 Keep in mind that CollectionViewDelegate conforms to ScrollViewDelegate:请记住,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)")
}

You can get the current page like below, index will be from 0 to (total page - 1)您可以像下面这样获取当前页面,索引将从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);
}

SWIFT 5斯威夫特 5

For example, put this method in your ViewController with extensions UICollectionViewDelegate,UICollectionViewDataSource例如,将此方法放在您的 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)")
    }

Swift 2.2斯威夫特 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)")
}

You can get the currentPage this way when the user end the dragging:当用户结束拖动时,您可以通过这种方式获取currentPage

Swift 5.6 Tested and works! 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)
}

Xamarin.iOS: Xamarin.iOS:

You can override DecelerationEnded method of UICollectionViewDelegate or subscribe to DecelerationEnded event of UICollectionView (custom delegate will be used under the hood).您可以覆盖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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM