UICollectionView:页面控制的当前索引路径

hzx*_*zxu 27 pagination objective-c uipagecontrol ios uicollectionview

我正在使用带有流布局的UICollectionView来显示单元格列表,我还有一个页面控件来指示当前页面,但似乎无法获取当前索引路径,我知道我可以获得可见单元格:

UICollectionView当前可见单元格索引

但是可以有多个可见的单元格,即使我的每个单元格都占据了屏幕的整个宽度,如果我将它滚动到两个单元格的两半,那么它们都是可见的,所以有没有办法只获得一个当前可见细胞的指数?

谢谢

and*_*kkt 50

您可以通过监视scrollViewDidScroll委托中的contentOffset来获取当前索引

它会是这样的

-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    NSInteger currentIndex = self.collectionView.contentOffset.x / self.collectionView.frame.size.width;

}
Run Code Online (Sandbox Code Playgroud)

  • 这很好,但我发现将相同的代码放在` - (void)scrollViewDidEndDecelerating :( UIScrollView*)scrollView`中,如果你需要更新一些UI,它会提供更平滑的效果. (14认同)
  • 我可以建议:`NSInteger currentIndex =(NSInteger)(self.collectionView.contentOffset.x/self.collectionView.frame.size.width + 0.5);`?当有半页或页面包含部分显示集合视图单元格时,这会产生更好的结果. (9认同)

Dmi*_*rov 19

从中心通过NSIndexPath获取页面.

即使您的页面不等于UICollectionView的宽度.

    func scrollViewDidScroll(scrollView: UIScrollView) {
    let center = CGPoint(x: scrollView.contentOffset.x + (scrollView.frame.width / 2), y: (scrollView.frame.height / 2))
    if let ip = collectionView.indexPathForItemAtPoint(center) {
        self.pageControl.currentPage = ip.row
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不错的方法,我会在做作之前从`ip.row` 到`pageControl.currentPage` 添加一个相等性测试,以避免在`UIPageControl` 逻辑上触发无用的开销 (2认同)

小智 12

当滚动运动停止时,您肯定需要捕获可见项目.使用下一个代码来完成它.

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    if let indexPath = myCollectionView.indexPathsForVisibleItems.first {
        myPageControl.currentPage = indexPath.row
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您的集合视图处于页面模式并且您的单元格宽度=屏幕宽度(如全屏页面ViewController),则它不起作用.生成的indexPath并不总是正确的. (3认同)
  • @Rikco 您是否找到了启用页面模式且单元格宽度 = 屏幕宽度的解决方案?这是我的确切情况 (2认同)

Ahm*_*adi 9

Swift 5.1

The easy way and more safety from nil crash

func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    if collectionView == newsCollectionView {
        if newsPager.currentPage == indexPath.row {
            guard let visible = newsCollectionView.visibleCells.first else { return }
            guard let index = newsCollectionView.indexPath(for: visible)?.row else { return }
            newsPager.currentPage = index
        }

    }
}
Run Code Online (Sandbox Code Playgroud)


Ram*_*has 6

  1. PageControl放在您的视图中或按Code设置。
  2. 设置UIScrollViewDelegate
  3. Collectionview- > cellForItemAtIndexPath(方法)中,添加以下代码以计算页面数,

    int pages = floor(ImageCollectionView.contentSize.width/ImageCollectionView.frame.size.width);
    [pageControl setNumberOfPages:pages];
    
    Run Code Online (Sandbox Code Playgroud)
  4. 添加ScrollView Delegate方法,

    #pragma mark - UIScrollViewDelegate for UIPageControl
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        CGFloat pageWidth = ImageCollectionView.frame.size.width;
        float currentPage = ImageCollectionView.contentOffset.x / pageWidth;
    
        if (0.0f != fmodf(currentPage, 1.0f))
        {
            pageControl.currentPage = currentPage + 1;
        }
        else
        {
            pageControl.currentPage = currentPage;
        }
        NSLog(@"finishPage: %ld", (long)pageControl.currentPage);
    }
    
    Run Code Online (Sandbox Code Playgroud)