4
2

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 1 year has passed since last update.

コードで作るContainer View Controller

Last updated at Posted at 2021-11-19

はじめに

この記事の目的は、コードから、Container View Controllerを作れるようになることです。
子ViewControllerが一つである単純な例で説明を行います。
参考文献の書籍の内容です。

ちなみに、storyboardからも、ContainerView(確かこんな名前のWidget)を使えばContainer View Controllerを作成可能です。

Container View Controllerとは

ViewControllerの中に他のViewControllerを表示するとき、
親になっているViewControllerをそう呼びます。

UINavigationControllerやUITabBarControllerなどは、Container View Controllerにあたります。

androidだとFragmentを持つActivityのようなものです。

方法

UIViewControllerでは、子ViewControllerを格納するためのchildrenプロパティが用意されていますが、プロパティを直接扱うことは非推奨です。
childrenプロパティに子ViewControllerを格納するには決まったお作法があり、技術書によれば、作法を破ると手痛い仕打ち(バグ)を受けるとのこと。
つまり、Container View Controllerの作成は、このお作法に則って行う必要があります。

お作法

add 子ViewController

  1. 親になるView Controller(以降親VCと呼称)のaddChild(_:)をコール。引数は子ViewController(以降子VCと呼称)。
  2. 親VCのview.addSubview(_:)によって、子VCのviewを加える。
  3. 子VCのdidMove(toParent:)を引数親VCでコール。

※1. 子VCが親VCのchildrenに格納されるだけでなく、自動で子VCのwillMove(toParant:)が引数親VCで呼ばれる。

remove 子ViewController

本記事の例では扱いませんが、一応removeも。

  1. 子VCのwillMove(toParent:)を引数nilでコール。
  2. 子VCのviewを親VCのviewから除外する。
  3. 子VCのremoveFromParent()をコール。

※3. 子VCがchildrenから除外されるだけでなく、自動で子VCのdidMove(toParant:)が引数nilで呼ばれる。

具体例

子としてPageViewControllerを持つcontaner view controllerを作成します。
初期画面のボタンを押すと、contaner view controllerに遷移するようにしました。

InitialViewController.swift

/// 初期表示画面。この画面の上にcontainer view controllerを表示してみる。

class InitialViewController: UIViewController {

~

// buttonのタッチイベントアクション。container view controllerを作成し、表示する処理を書きます。
    @IBAction func onButton(_ sender: UIButton) {
        // 親vc(contaner view controller)と子vcの作成
        let pvc = UIViewController()
        let cvc = MyPageViewController()// 前もって作成済みのもの。ペラペラめくれます。

        // 色を分けて見やすく
        pvc.view.backgroundColor = .white
        cvc.view.backgroundColor = .blue

        // addのお作法
        // 1
        pvc.addChild(cvc)
        // 2
        cvc.view.translatesAutoresizingMaskIntoConstraints = false
        pvc.view.addSubview(cvc.view)
        NSLayoutConstraint.activate([// 親vcの下半分に子vcを表示してみる
            cvc.view.leadingAnchor.constraint(equalTo: pvc.view.leadingAnchor),
            cvc.view.trailingAnchor.constraint(equalTo: pvc.view.trailingAnchor),
            cvc.view.bottomAnchor.constraint(equalTo: pvc.view.bottomAnchor),
            cvc.view.heightAnchor.constraint(equalTo: pvc.view.heightAnchor, multiplier: 0.5)
        ])
        // 3
        cvc.didMove(toParent: pvc)

        present(pvc, animated: true)
    }

~

}

Videotogif.gif

参考文献

より詳しくはこちら。

再利用可能なContainer View Controllerはこちらの記事が良さげでした。

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?