如何将 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)