24
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Swift】UIPageViewControllerとContainerViewを利用してタップで画面遷移

Last updated at Posted at 2018-10-31

今年の4月から新卒入社でSwiftを勉強し始めました。
Swift初心者のためお見苦しい点が多々あると思いますので、お気軽にご指摘のコメント等いただけたら幸いです。

#はじめに
UIPageViewControllerの勉強をした際、スワイプ以外で画面遷移が出来て感動したため記事にしようと思いました。

##作成したもの
親のViewControllerにあるボタンをタップをしたら親のViewControllerの中に置いたContainerViewが次のページに遷移する。
TapViewControllerGIF.gif

###UIPageViewControllerとは
スワイプで用意したViewControllerに画面遷移ができる
画面遷移時にアニメーションを付けられる

###ContainerViewとは
ViewControllerの中にViewControllerを配置することができるもの。
xibじゃなくてViewControllerを置きたい!という時に利用する。
ContainerViewは複数設置することも可能

##作ってみた
StoryBoard.png

親となるViewController(ContainerView)、UIPageViewController、子となるViewControllerを用意

Embed.png

ViewControllerにあるContainerViewから
「control+ドラッグ」でUIPageViewControllerに紐づけて「Embed」を選択すればOK

StoryboardID.png 画面遷移時にStoryboardIDを利用するため、StoryboardIDを設定
ViewController.swift
import UIKit

class ViewController: UIViewController {
    
    var pageViewController: UIPageViewController?
    
    // 画面の切り替えを見た目でわかりやすくための背景色設定用カラーパレット
    var pallet = [UIColor.red, UIColor.yellow, UIColor.blue, UIColor.green, UIColor.purple]

    // 表示するViewControllerを判断するための数字
    var cnt = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // PageViewControllerを取得
        pageViewController = children.first! as? UIPageViewController
        setViewController()
    }
    
    // 次へボタンが押されたら
    @IBAction func tapNextButton(_ sender: UIButton) {
        // 次の画面を表示するため、cntを1増やす
        cnt += 1
        setViewController()
    }
    
    func setViewController() {
        if cnt < pallet.count {
            let contentVC = storyboard?.instantiateViewController(withIdentifier: "ContentViewController") as! ContentViewController
          
            // 遷移先のViewControllerにpalletの色を送る
            contentVC.backColor = pallet[cnt]
            // PageViewControllerにViewControllerをセット
            self.pageViewController?.setViewControllers([contentVC], direction: .forward, animated: true,completion: nil)
        }
    }
}

##おまけ
###ドラッグでも画像遷移できるようにもしてみた

DragViewControllerGIF.gif

pageViewControllerのdataSourceを自身に設定
これをしないとドラッグしても反応しない

ViewController.swift
 // dataSourceの設定を追記
 pageViewController?.dataSource = self

UIPageViewControllerDataSourceを継承する

ViewController.swift

extension ViewController: UIPageViewControllerDataSource {

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

    }
}

継承するとメソッドを追加してね!という注意が出ます。
注意に従ってメソッドを追加すると上記のメソッドが追加されます。

このメソッドに関して

// In terms of navigation direction. For example, for 'UIPageViewControllerNavigationOrientationHorizontal', view controllers coming 'before' would be to the left of the argument view controller, those coming 'after' would be to the right.

→'UIPageViewControllerNavigationOrientationHorizo​​ntal'の場合、
**'before'**にあるビューコントローラは引数ビューコントローラ(現在表示されているViewController)の左側にあり、
**'after'**は右側にあります。

説明に従って適したViewControllerを準備していきます。

ViewController.swift
extension ViewController: UIPageViewControllerDataSource {
    // Beforeなので左側のViewController
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
      let contentVC = storyboard?.instantiateViewController(withIdentifier: "ContentViewController") as! ContentViewController
        if 0 < cnt {
            cnt -= 1
            contentVC.color = pallet[cnt]
        }
        return contentVC
    }
    // Afterなので右側のViewController
       func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        cnt += 1
        let contentVC = storyboard?.instantiateViewController(withIdentifier: "ContentViewController") as! ContentViewController
        if cnt < pallet.count {
            contentVC.color = pallet[cnt]
        }
        return contentVC
    }
}

##おわり
UIPageViewControllerが想像していたものと少し違う感じでしたが便利でした。
今回は1つのViewControllerで実装しましたが、もちろん複数のViewControllerでも実装可能です。

24
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?