如何将 UIPageControl 连接到 UICollectionView (Swift)
How to connect UIPageControl to UICollectionView (Swift)
我目前正在使用 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 开始时说用户在第三张图片上,即使它显示的是第一张图片。
有谁知道为什么会这样以及如何解决这个问题?
首先将您的 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
。
步骤 1 为集合视图和页面控件创建变量
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet var pageControl:UIPageControl!
步骤2设置Page Control的页数
override func viewDidLoad() {
super.viewDidLoad()
self.pageControl.numberOfPages = procedures.count
//Set the delegate
self.collectionView.delegate = self
}
*步骤3在scrollViewDidScroll函数中计算collection cell的宽度和当前页的索引。
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.
中测试
使用它可以顺利运行。
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)
}
在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)
我目前正在使用 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 开始时说用户在第三张图片上,即使它显示的是第一张图片。
有谁知道为什么会这样以及如何解决这个问题?
首先将您的 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
。
步骤 1 为集合视图和页面控件创建变量
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet var pageControl:UIPageControl!
步骤2设置Page Control的页数
override func viewDidLoad() {
super.viewDidLoad()
self.pageControl.numberOfPages = procedures.count
//Set the delegate
self.collectionView.delegate = self
}
*步骤3在scrollViewDidScroll函数中计算collection cell的宽度和当前页的索引。
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.
中测试使用它可以顺利运行。
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)
}
在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)