如何将 UIPageControl 连接到 UICollectionView (Swift)
Posted
技术标签:
【中文标题】如何将 UIPageControl 连接到 UICollectionView (Swift)【英文标题】:How to connect UIPageControl to UICollectionView (Swift) 【发布时间】:2017-12-11 03:11:48 【问题描述】:我目前正在使用 UICollectionView 来显示 3 张图像(每张图像跨越整个单元格)。我还有一个放置在 UICollectionView 顶部的 UIPageControl。我想要发生的是让 UIPageControl 显示图像的数量(在本例中为 3),以及用户当前正在查看的图像。我想要达到的效果是 Instagram 应用程序的效果。
我目前用来实现这种效果的方法是将 UIPageControl 的更新放在 UICollectionView 的 willDisplay
函数中,如下所示:
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
pictureDots.currentPage = indexPath.item
这可以正确连接集合视图和页面控件之间的分页效果。但是,我遇到的问题是 UIPageControl 开始说用户在第三张图像上,即使它正在显示第一张图像。
有谁知道为什么会发生这种情况以及如何解决这个问题?
【问题讨论】:
【参考方案1】:首先将您的UIPageControl
与您的UICollectionView
添加到您的故事板中,然后将它们作为插座连接到您的视图控制器。
@IBOutlet var pageControl: UIPageControl!
@IBOutlet var collectionView: UICollectionView!
调整UICollectionViewDataSource
中的numberOfItemsInSection
方法,将页面控件的计数设置为始终等于集合视图中的单元格数。
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
let count = ...
pageControl.numberOfPages = count
pageControl.isHidden = !(count > 1)
return count
最后,使用UIScrollViewDelegate
,我们可以知道UICollectionView
停在哪个单元格上。如果您没有使用UICollectionViewController
,您可能需要添加委托协议。
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
pageControl?.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView)
pageControl?.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
这是可能的,因为 UICollectionView
实际上是 UIScrollView
。
【讨论】:
可以有n页的情况下如何决定页数? @Hemang 页面数应该等于集合视图中的项目数。在numberOfItemsInSection
中,您通常会返回数据源中元素的数量。此处截取编号为count
,并设置页数。
在我的例子中,我有一个固定大小的集合视图,它将在一列中显示 5 行。因此,假设有 20 条记录,它将显示 4 列,每列 5 行。所以我需要的是获得 4 运行时。
如果 Collection 视图位于 TableView 单元格内,这会起作用吗?并且集合视图数据源和委托是 ViewController 类,它包含 TableView 而不是 TableViewcell 类【参考方案2】:
第 1 步为 Collection View 和 Page Control 创建变量
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet var pageControl:UIPageControl!
第二步设置Page Control的页数
override func viewDidLoad()
super.viewDidLoad()
self.pageControl.numberOfPages = procedures.count
//Set the delegate
self.collectionView.delegate = self
*Step 3在scrollViewDidScroll函数中计算集合单元格的宽度和当前页面的索引。
extension YourCollectionVC: UICollectionViewDataSource, UICollectionViewDelegate
override func scrollViewDidScroll(_ scrollView: UIScrollView)
let witdh = scrollView.frame.width - (scrollView.contentInset.left*2)
let index = scrollView.contentOffset.x / witdh
let roundedIndex = round(index)
self.pageControl?.currentPage = Int(roundedIndex)
注意:这个是水平显示的集合视图,垂直方向改变方法。
在 swift 4 中测试。
【讨论】:
【参考方案3】:使用它来顺利运行。
func scrollViewDidScroll(_ scrollView: UIScrollView)
let witdh = scrollView.frame.width - (scrollView.contentInset.left*2)
let index = scrollView.contentOffset.x / witdh
let roundedIndex = round(index)
self.pageControl.currentPage = Int(roundedIndex)
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView)
pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
【讨论】:
【参考方案4】:借助Combine
,我们可以轻松地将UIPageControl
与任何ScrollView
连接起来。
var collectionView: UICollectionView
var bin: Set<AnyCancellable> = []
var pageControl: UIPageControl
// setup observer
collectionView
.publisher(for: \.contentOffset)
.map [unowned self] offset in
Int(round(offset.x / max(1, self.collectionView.bounds.width)))
.removeDuplicates()
.assign(to: \.currentPage, on: pageControl) // may cause memory leak use sink
.store(in: &bin)
【讨论】:
以上是关于如何将 UIPageControl 连接到 UICollectionView (Swift)的主要内容,如果未能解决你的问题,请参考以下文章
将 UICollectionViewCell 连接到一个简单的视图控制器标题
我无法将 TableViewCell 按钮连接到 TableViewController!如何将 TableViewCell 中的值连接到 TableViewController?