iOS6的UICollectionView和UIPageControl – 如何获得可见的单元格?
在学习iOS6新function时,我得到了一个关于UICollectionView的问题。
我目前正在testingstream布局和滚动方向设置为水平,滚动和分页启用。 我已经将其大小设置为与我的自定义单元格完全相同,因此它可以一次显示一个单元格,通过向侧面滚动,用户将看到其他现有单元格。
它完美的作品。
现在我想添加和UIPageControl到我做的集合视图,所以它可以显示哪个单元格是可见的,有多less个单元格。
构build页面控件相当简单,定义了frame和numberOfPages。
问题标题所指出的问题是如何获取当前在集合视图中可见的单元格,以便可以更改页面控件的当前页面。
我已经尝试委托方法,如cellForItemAtIndexPath,但它是加载单元格,而不是显示它们。 didEndDisplayingCell在单元格不再显示时触发,与我所需要的相反。
它似乎-visibleCells和-indexPathsForVisibleItems,集合视图方法,是我的正确select,但我遇到了另一个问题。 什么时候触发他们?
在此先感谢,希望我能让自己清楚明白,以便你们能理解我!
您必须将自己设置为UIScrollViewDelegate
并像下面这样实现scrollViewDidEndDecelerating:
方法:
Objective-C的
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { CGFloat pageWidth = self.collectionView.frame.size.width; self.pageControl.currentPage = self.collectionView.contentOffset.x / pageWidth; }
迅速
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { let pageWidth = self.collectionView.frame.size.width pageControl.currentPage = Int(self.collectionView.contentOffset.x / pageWidth) }
我也苦苦挣扎了一段时间,然后build议查看UICollectionView的父类。 其中一个恰好是UIScrollView ,如果您将自己设置为UIScrollViewDelegate ,则可以访问非常有用的方法,例如scrollViewDidEndDecelerating ,这是更新UIPageControl的好地方。
我会build议一些调整计算和处理,因为它会更快地更新页面控制在任何滚动位置更准确。
下面的解决scheme适用于任何滚动视图或它的子类(UITableView UICollectionView和其他)
在viewDidLoad方法中写这个
scrollView.delegate = self
然后使用您的语言的代码:
Swift 3
func scrollViewDidScroll(_ scrollView: UIScrollView) { let pageWidth = scrollView.frame.width pageControl.currentPage = Int((scrollView.contentOffset.x + pageWidth / 2) / pageWidth) }
Swift 2:
func scrollViewDidScroll(scrollView: UIScrollView) { let pageWidth = CGRectGetWidth(scrollView.frame) pageControl.currentPage = Int((scrollView.contentOffset.x + pageWidth / 2) / pageWidth) }
目标C
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat pageWidth = self.collectionView.frame.size.width; self.pageControl.currentPage = (self.collectionView.contentOffset.x + pageWidth / 2) / pageWidth; }
使用较less代码的另一个选项是使用可见项索引path并设置页面控制。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { self.pageControl.currentPage = [[[self.collectionView indexPathsForVisibleItems] firstObject] row]; }
- 将PageControl放置在您的视图中或由代码设置。
- 设置UIScrollViewDelegate
- 在Collectionview – > cellForItemAtIndexPath(Method)中添加下面的代码来计算页数,
int pages = floor(ImageCollectionView.contentSize.width / ImageCollectionView.frame.size.width); [pageControl setNumberOfPages:pages];
添加ScrollView委托方法,
编译标记 – 用于UIPageControl的UIScrollVewDelegate
- (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); }
我知道这是一个旧的,但我只需要再次实现这种function,并有一点补充,这给了一个更完整的答案。
首先:使用scrollViewDidEndDecelerating
假定用户在拖动时抬起手指(更像是轻弹动作),因此存在减速阶段。 如果用户拖动手指, UIPageControl
仍然会在拖动开始之前指示旧页面。 而使用scrollViewDidScroll
callback意味着视图在拖拽和轻拂后以及在拖拽和滚动期间都被更新,因此对用户来说,感觉更加敏感和准确。
其次:依靠计算所选索引的页面宽度,假定所有单元具有相同的宽度,并且每个屏幕有一个单元。 利用indexPathForItemAtPoint
上的indexPathForItemAtPoint
方法提供了一个更UICollectionView
结果,这将适用于不同的布局和单元大小。 下面的实现假设框架的中心是页面pagecontrol
要表示的所需单元格。 另外,如果有单元间距,那么在滚动期间,当selectedIndex可能是零或可选的时候会有时间,所以在设置pageControl之前需要检查和解包。
func scrollViewDidScroll(scrollView: UIScrollView) { let contentOffset = scrollView.contentOffset let centrePoint = CGPointMake( contentOffset.x + CGRectGetMidX(scrollView.frame), contentOffset.y + CGRectGetMidY(scrollView.frame) ) if let index = self.collectionView.indexPathForItemAtPoint(centrePoint){ self.pageControl.currentPage = index.row } }
还有一件事 – 在UIPageControl
上设置页面的数量,如下所示:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { self.pageControl.numberOfPages = 20 return self.pageControl.numberOfPages }
简单的斯威夫特
public func scrollViewDidEndDecelerating(scrollView: UIScrollView) { pageControl.currentPage = (collectionView.indexPathsForVisibleItems().first?.row)! }
如果您实现UICollectionViewDelegate
则已经实现了UIScrollViewDelegate