カルーセルでpage controlを実装してみた経験より(2020-07-27)
畑田です。
page controlはスクロールしたときに今いるcellを教えてくれるポチポチのことです。pageControl = UIPageControl()
とかで簡単にインスタンスかできます。全てコードで書いていきます。
環境
Swift version 5.2.4
Xcode version 11.6
UIScrollViewDelegateいるねんて
あれは、本来scroll viewと使うものなのかな。
ということで、scrollが始まったり終わったりすることを検知してくれる関数が用意されているので、そこで今いるcellをpageControl.currentPage: Int
に教えてあげれば良い感じです。
スクロールを検知してくれる関数は、UIScrollViewDelegateプロトコルが定義してねって言っているので、とりあえず今のview controllerのextensionでadhereしてあげて、その中で書きます。
ここで注意事項なのですが、UIPageControl
はnumberOfPages
propertyを設定しないと正常に動かないので、collectionView
にcellの数を教えるメソッド内できちんと設定しましょう。
extension ModeSelectViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let numberOfItems = 2
pageControl.numberOfPages = numberOfItems
return numberOfItems
}
// skip details
}
extension ModeSelectViewController: UIScrollViewDelegate {
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)
}
}
終わりです。
というのも(なんか知らないけど)indexPathをポイって渡せないので今のオフセットを幅で割って無理やりやっています。
以下追記です。(2020-08-26)
上では元のview controllerをUIScrollViewDelegate
protocolに批准させて、func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
、func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView)
のなかでpage controlのcurrentPage
propertyを代入していましたが、今回はUIScrolllView
ではなくUICollectionView
を使っているので以下のように実装できます。
extension ModeSelectViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
// page control
pageControl.currentPage = indexPath.row
// skip details
}
}