SwiftUI 2.0 & UIKit & Storyboard (Part 3)

# Part 3: Storyboard & SwiftUI 2.0
The article is broken in three different parts:

- [Part 1: SwiftUI 2.0 & Storyboard](https://qiita.com/loic-meister-guild/items/61256e5edf06af48eb30)
- [Part 2: SwiftUI 2.0 & UIKit](https://qiita.com/loic-meister-guild/items/a880dbc12dc844cbacaa)
- Part 3: Storyboard & SwiftUI 2.0 ([日本語](https://qiita.com/loic-meister-guild/items/609a0d91498776b2cc85))

The third part is about using SwiftUI 2.0 elements in a Storyboard application.

## Use SwiftUI views from UIKit views and the Storyboard
This is the opposite of the 2 previous section, and is useful to add new views to a legacy application or refactor parts of a legacy application using SwiftUI.

### The XCode Project
Create a new __SwiftUI__ App project
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531993/2eb13d16-1b15-5b6c-0a80-963291f9665d.png)
Name the project
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531993/40aec66d-90bb-91dd-a4e6-4e0b8ea54cf7.png)
Create a new __SwiftUI View__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531993/2f326aa3-6637-e3c4-3575-4d9d5696b6e1.png)
Name it
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531993/7d2a672c-0aed-e4f9-97da-345da8142e03.png)
Then populate it with UI elements and make it the initial view controller
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531993/b21a0617-4ebc-0c72-a833-c0f659e69458.png)
Now we have a Storyboard project containing a storyboard with a UIViewController that contains a label and a button ...
### The `Storyboard UIViewController`
The UIViewController in the storyboard has its own subclass `ViewController`.

Rename the subclass to `UIKitViewController` and add an `IBAction` linked to the button `TouchUpInside` event:

```Swift:UIKitViewController.swift
import UIKit
import SwiftUI

class UIKitViewController: UIViewController {
    @IBAction func toSwiftUI(_ sender: Any) {
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
```

To display the `SwiftUI` view, use a [`UIHostingController`](https://developer.apple.com/documentation/swiftui/uihostingcontroller):

```Swift:Swift
UIHostingController(rootView: _)
```

In the `IBAction` of the `UIKitViewController`, init a [`UIHostingController`](https://developer.apple.com/documentation/swiftui/uihostingcontroller) with  `SwiftUIView`, then use it just like a normal `UIViewController` to present the __SwiftUI__ view:

```Swift:UIKitViewController.swift
import UIKit
import SwiftUI

class UIKitViewController: UIViewController {
    @IBAction func toSwiftUI(_ sender: Any) {
        let view = UIHostingController(rootView: SwiftUIView())
        self.present(view, animated: true, completion: nil)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
```
Now let's write the `SwiftUI` view.
### The `SwiftUI View`
The `SwiftUI View` is composed of 4 elements:
- A `Text` element displaying the text "SwiftUI"
- A `Text` element displaying the content of the `labelText` variable
- A `TextField` element binded to the `inputText` variable
- A button to change the content of `labelText` to the content of `inputText`

```Swift:SwiftUIView.swift
import SwiftUI

struct SwiftUIView: View {
    @State var labelText = "Initial Text"
    @State var inputText = ""
    
    var body: some View {
        VStack {
            Text("SwiftUI")
            Spacer()
            Text(labelText)
            Spacer()
            TextField("Input", text: $inputText)
            Spacer()
            Button {
                labelText = inputText
                inputText = ""
            } label: {
                Text("Change Text")
            }
        }
    }
}
```
Now let's test the `IBAction`!
### The App
Launch the App, and in the `Storyboard` view, click on the `To SwiftUI!` button to present the `SwiftUI` view:
![storyboard-swftui-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531993/927af71e-d361-645d-a808-764ec355c542.png)
In the `SwiftUI` view input some new text in the textfield:
![storyboard-swftui-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531993/01adad25-63d2-d2a9-fc1b-1c2fd612208c.png)
Then, click on the `Change Text` button, and the "Initial Text" in the second `Text` element gets replaced with the new text:
![storyboard-swftui-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531993/e890dc19-b117-9a62-36d3-aaf325e0c02e.png)
It works!