【Swift】PageViewControllerで画面遷移する

#はじめに
今回はPageViewControllerを使ってスワイプした時に画面遷移をさせてみます。

![ezgif.com-gif-maker (4).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/72cced08-e392-6285-700a-59e3754a904e.gif)

#GitHub

https://github.com/0429oonishi/PageViewController-Sample

#実装
![ScreenShot 2021-06-12 0.08.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/f1d80b5d-9b93-b608-8034-40916f283ba7.png)
![ScreenShot 2021-06-12 0.08.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954451/741f0595-5eec-1db0-7443-66bd6b18ce65.png)

一番左がPageViewControllerで、赤色がFirstViewController, 青色がSecondViewController, 緑色がThirdViewControllerです。

そして、PageViewControllerというUIPageViewControllerを継承したクラスを作ります。

```swift
final class PageViewController: UIPageViewController
```

色のついたViewControllrにStoryboardIDとSwiftファイルを用意してください。
全体のコードは以下の通りです。

```swift
final class PageViewController: UIPageViewController {
    
    private var controllers = [UIViewController]()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupPageViewController()
        
    }
    
    private func setupPageViewController() {
        let firstVC = storyboard?.instantiateViewController(
            withIdentifier: "FirstViewController"
        ) as! FirstViewController
        let secondVC = storyboard?.instantiateViewController(
            withIdentifier: "SecondViewController"
        ) as! SecondViewController
        let thirdVC = storyboard?.instantiateViewController(
            withIdentifier: "ThirdViewController"
        ) as! ThirdViewController
        controllers = [firstVC, secondVC, thirdVC]
        setViewControllers([controllers[0]], direction: .forward, animated: true, completion: nil)
        self.dataSource = self
    }
    
}

extension PageViewController: UIPageViewControllerDataSource {
    
    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return controllers.count
    }
    
    func pageViewController(_ pageViewController: UIPageViewController,
                            viewControllerBefore viewController: UIViewController) -> UIViewController? {
        if let index = controllers.firstIndex(of: viewController),
           index < controllers.count - 1 {
            return controllers[index + 1]
        }
        return nil
    }
    
    func pageViewController(_ pageViewController: UIPageViewController,
                            viewControllerAfter viewController: UIViewController) -> UIViewController? {
        if let index = controllers.firstIndex(of: viewController),
           index > 0 {
            return controllers[index - 1]
        }
        return nil
    }
    
}
```

#解説

表示するためのViewControllerを配列に格納して管理します。

```swift
    let firstVC = storyboard?.instantiateViewController(
        withIdentifier: "FirstViewController"
    ) as! FirstViewController
    let secondVC = storyboard?.instantiateViewController(
        withIdentifier: "SecondViewController"
    ) as! SecondViewController
    let thirdVC = storyboard?.instantiateViewController(
        withIdentifier: "ThirdViewController"
    ) as! ThirdViewController
    controllers = [firstVC, secondVC, thirdVC]
    // 最初の画面を設定
    setViewControllers([controllers[0]], direction: .forward, animated: true, completion: nil)
    // ここでデリゲートも設定しておく
    self.dataSource = self
```

`setViewControllers(...)`を使い、最初に表示する画面を設定します。 [setViewControllers](https://developer.apple.com/documentation/uikit/uipageviewcontroller/1614087-setviewcontrollers)

```swift
setViewControllers([controllers[0]], direction: .forward, animated: true, completion: nil)
```

`UIPageViewControllerDataSource`を見ていきます。

ページ数を返します。

```swift
func presentationCount(for pageViewController: UIPageViewController) -> Int {
    return self.controllers.count
}
```

左スワイプ（Before）した時の表示する画面を返します。

```swift
func pageViewController(_ pageViewController: UIPageViewController,
                        viewControllerBefore viewController: UIViewController) -> UIViewController? {
    if let index = controllers.firstIndex(of: viewController),
       index < controllers.count - 1 {
        return controllers[index + 1]
    }
    return nil
}
```

右スワイプ（After）した時の表示する画面を返します。

```swift
func pageViewController(_ pageViewController: UIPageViewController,
                        viewControllerAfter viewController: UIViewController) -> UIViewController? {
    if let index = controllers.firstIndex(of: viewController),
       index > 0 {
        return controllers[index - 1]
    }
    return nil
}
```


#おわりに
[PageViewController](https://developer.apple.com/documentation/uikit/uipageviewcontroller)
PageViewControllerを使った画面遷移をしてみました。