【swift】ちょい足しレシピ①!UIPageViewControllerを無限スクロールにしてみる

もくじ

毎度どうもこんにちは。iOSをメインに開発しているロッキーカナイです。

今回から「ちょい足しレシピ」なるシリーズを開始しようと思ってます。ここをこう変更するとこういうこともできるよ!という、ちょいとしたことを綴ります。

今回はニュースアプリなどでよく使われているUIPageViewControllerにちょい足しして無限スクロールができるようにする方法を紹介します。

環境 XCode9 / Swift4


・Xcodeのプロジェクトを新規で作る時に出てくるテンプレートのPage-Based Appを使います。


・プロジェクト登録を終えると、ページビューコントローラーが動作する必要最低限のコーディングがされた状態になってます。
関連ファイルは以下の通りです。
Main.storyboard・・・・・レイアウト
RootViewController・・・ページビューコントローラー
DataViewController・・・各ベージビュー
ModelController・・・・・ページ制御ロジック

準備篇として始める前に2点変更をします。
・見やすくする為ページ遷移アニメーションを変更
・今の状態だと1月から12月まであり多いので5ページに減らします

1 見やすくする為ページ遷移アニメーションを変更
RootViewControllerのviewDidLoadメソッド内

self.pageViewController = UIPageViewController(transitionStyle: .pageCurl, navigationOrientation: .horizontal, options: nil)

self.pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)

2 今の状態だと1月から12月まであり多いので5ページに減らします
ModelControllerのinitメソッドを

override init() {
        super.init()
        // Create the data model.
        let dateFormatter = DateFormatter()
        pageData = dateFormatter.monthSymbols
    }

 override init() {
        super.init()
        for i in 0 ..< 5 {
            pageData.append(String(i))
        }
    }
   

・ここまでの動作の動画

1 無限スクロール可能にする
ModelControllerの修正

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        var index = self.indexOfViewController(viewController as! DataViewController)
        if (index == 0) || (index == NSNotFound) {
            return nil
        }
        
        index -= 1
        return self.viewControllerAtIndex(index, storyboard: viewController.storyboard!)
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        var index = self.indexOfViewController(viewController as! DataViewController)
        if index == NSNotFound {
            return nil
        }
        
        index += 1
        if index == self.pageData.count {
            return nil
        }
        return self.viewControllerAtIndex(index, storyboard: viewController.storyboard!)
    }

   func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        var index = self.indexOfViewController(viewController as! DataViewController)
        index -= 1
        return self.viewControllerAtIndex(self.enableDataIndex(index), storyboard: viewController.storyboard!)
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        var index = self.indexOfViewController(viewController as! DataViewController)
        if index == NSNotFound {
            return nil
        }
        
        index += 1
        return self.viewControllerAtIndex(self.enableDataIndex(index), storyboard: viewController.storyboard!)
    }

    func enableDataIndex(_ index: Int) -> Int {
        var dataIndex       = index
        let pageDataCount   = self.pageData.count
        var isMinus         = false
        
        if dataIndex < 0 {
            dataIndex *= -1
            isMinus = true
        }
        while dataIndex >= pageDataCount {
            dataIndex -= pageDataCount
        }
        if isMinus {
            dataIndex = pageDataCount - dataIndex
        }
        return dataIndex
    }

無限スクロール可能にするために、pageViewController:viewControllerBeforeメソッドとpageViewController: viewControllerAfterメソッドでマイナス値やself.pageData.count以上の値でもスルーするようにします。
本来無効な値が通るので、新規追加したenableDataIndexメソッドで正しいページの要素値を算出することで無限スクロールできるようにしました。

・完成後の動画

これを使ってなにか面白いことができそうですね。
以上、「ちょい足しレシピシリーズ第1弾目のUIPageViewControllerを無限スクロールにしてみる」でした!
はたして第2弾目はあるのでしょうか・・・

関連する記事

もっと見る