如何将 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 连接到一个简单的视图控制器标题

将 UIView 添加到 ScrollView 以进行分页

我无法将 TableViewCell 按钮连接到 TableViewController!如何将 TableViewCell 中的值连接到 TableViewController?

如何将 UIPageControl 与 iCarousel 一起使用?

如何将 HTML 页面连接到 MongoDB?

将 Auth0 连接到我的后端后,如何将其连接到我的 NextJS 前端?