storyboardに紐づけられたViewControllerを取得する方法

一番書きたいところは後半のイニシャライザ付きのViewControllerをR.swiftで呼ぶところです．前半は全てのパターンを網羅するために書いています．

## storyboardのファイル名とIDを指定する


準備として、`example.storyboard`ファイルを作成し、ViewControllerを配置し、Storyboard IDを書き込みます。(画面右)
![スクリーンショット 2021-08-29 9.12.46.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/136a0806-0cb0-a09c-ea5b-d0c562097f91.jpeg)
### イニシャライザに値が必要でない場合

イニシャライザに値が必要でない場合という表現が適切かは分かりません。


```swift
let vc: UIViewController = UIStoryboard(name: "main", bundle: nil).instantiateViewController(identifier: "second")
```
### イニシャライザに値が必要な場合
イニシャライザに値が必要な場合とは、

```swift
class: UIViewController {
    private let text: String
    init?(coder: NSCoder, text: String) {
        self.text = text
        super.init(coder: coder)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
```

のように、ViewControllerが値を持っていない変数を持っている場合を指しています。

```swift
let vc: UIViewController = UIStoryboard(name: "main", bundle: nil).instantiateViewController(identifier: "second") { coder in
        return SecondViewController(coder: coder, text: "text")
}
```

## storyboardのファイル名のみを指定し、initialViewControllerを指定する。

準備として、`example.storyboard`ファイルを作成し、ViewControllerを配置し、Is Initial ViewControllerにチェックを入れます。
![スクリーンショット 2021-08-29 9.11.46.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/e639fb7d-e0cb-4741-9118-5116211f7b2b.jpeg)

### イニシャライザに値が必要ない場合
```swift
let vc: UIViewController = UIStoryboard(name: "main", bundle: nil).instantiateInitialViewController()!
```

### イニシャライザに値が必要な場合

```swift
let vc: UIViewController = UIStoryboard(name: "main", bundle: nil).instantiateInitialViewController { coder in
        return SecondViewController(coder: coder, text: "hoge")
    }!
```

## R.swiftを使い、initialViewControllerを指定する

準備として、R.swiftを拡張します。

```swift
import Rswift
public extension StoryboardResourceWithInitialControllerType {
    
    @available(iOS 13.0, tvOS 13.0, *)
    func instantiateInitialViewController<ViewController>(creator: ((NSCoder) -> ViewController?)? = nil) -> UIViewController? where ViewController: UIViewController {
        UIStoryboard(resource: self).instantiateInitialViewController { coder in
            creator?(coder)
        }
    }
    
    @available(iOS 13.0, tvOS 13.0, *)
    func instantiateViewController<ViewController>(identifier: StoryboardViewControllerResource<ViewController>,creator: ((NSCoder) -> ViewController?)? = nil) -> UIViewController where ViewController: UIViewController {
        UIStoryboard(resource: self).instantiateViewController(identifier: identifier.description) { coder in
            return creator?(coder)
        }
    }
    
}
```
### イニシャライザに値が必要ない場合

```swift
let vc: UIViewController = R.storyboard.main.instantiateInitialViewController()!
```
### イニシャライザに値が必要な場合

```swift
let vc = R.storyboard.main.instantiateInitialViewController { coder in
            return SecondViewController(coder: coder, text: "")
        }!
```

## R.swiftを使い、IDを指定する
### イニシャライザに値が必要ない場合
```swift
let vc: UIViewController = R.storyboard.main.second()
```

### イニシャライザに値が必要な場合

```swift
let vc: UIViewController = R.storyboard.weather.instantiateViewController(identifier: R.storyboard.weather.second) { coder in
            return SecondViewController(coder: coder, text: "")
        }
```