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

SwiftUI 4泊5日の旅(2日目:プロジェクト構成)

Last updated at Posted at 2020-05-04

はじめに

前回SwiftUI Tutorialsの冒頭に沿った内容でしたが、今回はプロジェクト構成の話です。
前回いじったContentViewは一体どこから呼ばれてたのか?

SceneDelegateで最初の画面を出す

その答えはSceneDelegateです。
スクリーンショット 2020-05-03 23.35.12.png
まず、Info.plistApplication Scene Manifestにて、SceneDelegateがデフォルトで指定されています。
スクリーンショット 2020-05-03 22.25.07.png
このためアプリ起動時、SceneDelegateの以下部分が呼ばれます。

SceneDelegate.swift
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 
    {
        let contentView = ContentView()
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
    •••
}

rootViewController ContentViewを与えているので、最初の画面が表示されます。

UIHostingControllerを用いてUIKitとSwiftUIを繋ぐ

UIHostingControllerは、SwiftUI用の新しいUIViewControllerです。
つまり、これを従来のUIWindowに渡すことで、UIKitからSwiftUIに繋いでいるわけです。

また、UIHostingControllerを継承したカスタムクラスを用意して、

MyHostingController.swift
import SwiftUI

class MyHostingController: UIHostingController<ContentView> {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder, rootView: ContentView())
    }
}

このようにContentViewの指定をカスタムクラス内で行えば、外からは普通のControllerに見えるので、Storyboardから表示させることもできます。iOS 12以前で使ったらクラッシュしますけどね。

UIViewRepresentableを用いてSwiftUIからUIKitに繋ぐ

逆にSwiftUI側でUIKitのパーツを使うこともできます。例えばUITextViewを使いたい場合、

TextView.swift
struct TextView: UIViewRepresentable {
    @Binding var text: String

    func makeUIView(context: Context) -> UITextView {
        return UITextView()
    }

    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.text = text
    }
}

こんなクラスを作って、生成時と更新時の処理を書きます。利用側では、

ContentView.swift
struct ContentView: View {
    @State private var message = "Hello, World!"
    var body: some View {
        TextView(text: $message)
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
    }
}

のように書きます。messageには@Stateが付いてるので、データが変更されたら表示に即反映されます。

PreviewProviderでプレビュー可能にする

ContentViewには、デフォルトで以下の記述があります。

ContentView.swift
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

ここにプレビューしたいViewを書いておくと、Xcodeが自動で見つけてプレビュー対象にしてくれます。

プロジェクト構成まとめ

SwiftUIに必要なものは以下です。
Info.plistApplication Scene Manifest定義
SceneDelegate
UIHostingControllerrootViewに渡すView
・プレビューしたい場合PreviewProvider

最後に

次回はSwiftUIで簡単に実装できる何らかのレイアウトを紹介します。
従来と比べてどれくらい簡単になるかを体験しましょう!

で、1日目すっかり忘れてたんですが、これは「4泊5日のGW旅行」なので、グルメ写真も載せます。

お昼は松島町の「さんとり茶屋」さんで穴子丼をいただきました😋

夜は旅行の定番、懐石料理。さぁ乾杯!!
※写真は2017年GW旅行のものです

0
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
0
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?