SwiftUIからStoryboardを表示させる  またその逆 ?



# SwiftUIでStoryboardは使えます ?


- 2019/12/24 動画を追加しました

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">動画 SwiftUIからStoryboardを表示させる またその逆 ?<a href="https://t.co/vFyth2QIBj">https://t.co/vFyth2QIBj</a></p>&mdash; 株式会社パパスサン (@papassan) <a href="https://twitter.com/papassan/status/1209252561934381058?ref_src=twsrc%5Etfw">December 23, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



- 2019/12/23 修正します、ContentView.swiftを入れ替える前にStoryboardにClassはViewControllerを選択できませんよね? 入れ替えた後に選択してください、済みませんでした

- 2019/12/23 投稿

# 目的 ?

- タイトルの通り

# 目的の少し解説 ? 

- お急ぎの方は必要条件を読んで先に進んでください
- SwiftUI以前に作成した沢山のStoryboardが使いたい ?
- 新規にプロジェクトをSwiftUIで作成したい


# 挙動

> 挙動は「SwiftUIViewを表示します!」ボタンをタップするとSwiftUIのViewが表示して「Storyboardを表示します!」ボタンをタップするとUIViewのStoryboardのViewが表示します、Storyboardには遷移したことが分かるように背景に色を変えるとかをしてください、それと、UIViewにはContentView.swiftへ戻るためのボタンを設置してボタンのCodeと接続してください、そのボタンをタップするとContentView.swiftが表示します、今回はContentView.swiftに全てのCodeを記帳しましたがお好みで別ファイルにしてください、

- 本当はgitとかで配布したいのですが、私はgitの使い方がよくわかりません 勉強中です

# 必要条件 ?

- Xcode Version 11.3 で New Project で Single View Appを選択して Nextをタップします
- 私の場合、Product Nameは「StoryboardWithSwiftUIView」と命名しました
- Language: Swift
- User Interface: SwiftUI でNextをタップします



# 作成が終わったらStoryboadを追加作成します

- ContentView.swiftで右タップでNew Fileをタップ
- User InterfaceをStoryboadにする
- 「Main.storyboard」と命名して作成します
- Storyboadを追加してClassはViewControllerに設定してください
- 添付したContentView.swiftを入れ替える
- 他のファイルは一切いじってません

# Storyboadの作成が終わったら ?

- ContentView.swiftを入れ替える

# ContentView.swiftを入れ替える

```ContentView.swift

//
//  ContentView.swift
//  StoryboardWithSwiftUIView
//
//  Created by 福田 敏一 on 2019/12/23.
//  Copyright © 2019 株式会社パパスサン. All rights reserved.
//

import UIKit
import SwiftUI

struct ContentView: View {

    @State var showingDetail0 = false
    @State var showingDetail1 = false
    
    var body: some View {
        VStack {
            Spacer()
            Text("アクセス方法")
            .font(.largeTitle)
            Spacer()
            Button(action: {
                self.showingDetail0.toggle()
            }) {
                Text("SwiftUIViewを表示します!")
                .font(.title)
            }.sheet(isPresented: $showingDetail0) {
/*⭐️*/          SwiftUI()
            }
            Spacer()
            Button(action: {
                self.showingDetail1.toggle()
            }) {
                Text("Storyboardを表示します!")
                .font(.title)
            }.sheet(isPresented: $showingDetail1) {
/*⭐️⭐️*/         UIView()
            }
            Spacer()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
/*⭐️*/
struct SwiftUI: View {

    var body: some View {
        Text("Hello world")
    }
    
}

struct SwiftUI_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUI()
    }
    
}
/*⭐️・ここまで*/

/*⭐️⭐️*/
struct UIView: View {
    var body: some View {
/*✳️*/          UIViewControllerViewWrapper {
                Text("Hello world")
        }
    }

}

struct UIView_Previews: PreviewProvider {
    static var previews: some View {
        UIView()
    }
    
}
/*⭐️⭐️・ここまで*/

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

print("5-91・通過・ViewController")
    }
    
//⭐️解説⭐️ Main.storyboardのViewにButtonを設置して接続してください
    @IBAction func 戻る(_ sender: UIButton) {
        let contentView: UIHostingController = UIHostingController(rootView: ContentView())
        contentView.view.frame = self.view.bounds
        self.addChild(contentView)
        self.view.addSubview(contentView.view)
        contentView.didMove(toParent: self)
    }
    
}
/*✳️✳️・ここから*/
class ViewControllerWithStoryboard: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
print("2-109・通過・viewDidLoad")
        
    }
    // View構築後の処理
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
print("4-115・通過・viewDidAppear")

        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let nextView = storyboard.instantiateInitialViewController() as! ViewController
        nextView.modalPresentationStyle = .fullScreen
        present(nextView, animated: false, completion: nil)
        
    }
}
/*✳️✳️・ここまで*/

/*✳️・ここから*/
struct UIViewControllerViewWrapper<Content: View>: UIViewControllerRepresentable {
        
    //The type of view controller to present.
    //Required.
    typealias UIViewControllerType = ViewControllerWithStoryboard

    var content: () -> Content

    func makeUIViewController(context: Context) -> ViewControllerWithStoryboard {
    //Creates the view controller object and configures its initial state.
    //Required.
        let viewControllerWithStoryboard = ViewControllerWithStoryboard()
print("1-139・通過・makeUIViewController・")
        return /*✳️✳️*/viewControllerWithStoryboard
    }
/*⭐️*/
    func updateUIViewController(_ uiviewController: ViewControllerWithStoryboard, context: Context) {
        //Updates the state of the specified view controller with new information from SwiftUI.
        //Required.
print("3-146・通過・updateUIViewController・")
    }
}
/*✳️・ここまで*/

```

# 実行結果.swift

```実行結果.swift

// 「Storyboardを表示します!」をタップした時の実行結果です

1-138・通過・makeUIViewController・
2-109・通過・viewDidLoad
3-145・通過・updateUIViewController・
3-145・通過・updateUIViewController・
4-115・通過・viewDidAppear
5-91・通過・ViewController
3-145・通過・updateUIViewController・

```

# 私の感想と意見ですが ?

struct UIViewControllerViewWrapperのfunc makeUIViewControllerでclass ViewControllerWithStoryboardを読んでからoverride func viewDidAppearから表示したいclass ViewControllerを呼んでいますが ? 次回はfunc makeUIViewControllerから直接Storyboardを呼びたいと願っています



- ここまで