7
6

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 3 years have passed since last update.

【Swift】コードでViewControllerを生成して画面遷移と値渡しをする方法

Posted at

はじめに

Storyboard は画面レイアウトの作成にだけ使用して、
ViewController の初期化と画面遷移はコードでやってしまいたい人向けです。
自分はよくこんな感じにやってます。

前準備

ファイルの構成について

自分は Storyboard と ViewController は1対1になるようにしています。
なので基本的に Storyboard と ViewController の名前は同じにします。

こんな感じの構成です。
FirstViewController が遷移元の画面で、SecondViewController が遷移先の画面だと思ってください。

フォルダの構成
スクリーンショット 2020-05-06 20.46.43.png

このとき Storyboard 側で Custom Class の設定と、
Is Initial View Controller の設定をすることを忘れないでください。

Custom Class Is Initial View Controller
スクリーンショット 2020-05-06 20.49.06.png スクリーンショット 2020-05-06 20.49.16.png

ViewController について

ViewController はそれぞれこんな感じです。
例として SecondViewController の number に数字を渡したいとします。

// FirstViewController

final class FirstViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
// SecondViewController

final class SecondViewController: UIViewController {
    
    // ここに値渡しで数字を渡したい
    var number: Int!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print(number)
    }
}

画面遷移

では本題に入ります。

画面遷移は Storyboard から ViewController を生成して、
ViewController の present() もしくは NavigationController の pushViewController() のどちらかで遷移します。

// Storyboard から遷移先の ViewController を生成
// 簡易的なコードなので強制キャストしています。
let vc = UIStoryboard(name: "SecondViewController", bundle: nil).instantiateInitialViewController() as! SecondViewController

// `present()` で遷移する場合
present(vc, animated: true, completion: nil)

// NavigationController の `pushViewController()` で遷移する場合
navigationController?.pushViewController(vc, animated: true)

値渡し

画面遷移の段階で遷移先の ViewController を生成しているので、
そこに渡してしまうだけです。

// Storyboard から遷移先の ViewController を生成
// 簡易的なコードなので強制キャストしています。
let vc = UIStoryboard(name: "SecondViewController", bundle: nil).instantiateInitialViewController() as! SecondViewController

// 遷移先の `number` に値を渡す
vc.number = 10

// ...

おまけ: ViewController の初期化を簡単にする

Storyboard から ViewController を生成するコードは冗長で、
引数に Storyboard の名前を文字列として取るのでタイプミスも発生しやすいです。

なので Storyboard の初期化、初期化した Storyboard から ViewController の生成をまとめてやってしまう Static な関数を UIViewController の Extension として追加して、より簡単に初期化できるよう拡張します。

ただし、以下の Extension は Storyboard と ViewController の名前が同じであることを前提としています。

extension UIViewController {
    static func instantiate() -> Self {
        guard let vc = UIStoryboard(name: String(describing: self), bundle: nil).instantiateInitialViewController() as? Self else {
            fatalError("Storyboard named \(String(describing: self)) was not found.")
        }
        return vc
    }
}

使用するときはこんな感じです。

let secondVC = SecondViewController.instantiate()
7
6
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
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?