page controlを実装してみた経験より(2020-07-27)

カルーセルで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してあげて、その中で書きます。
ここで注意事項なのですが、UIPageControlnumberOfPages 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
    }
}

おすすめ

人気の投稿

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です