はじめに
前回はSwiftUI Tutorialsの冒頭に沿った内容でしたが、今回はプロジェクト構成の話です。
前回いじったContentView
は一体どこから呼ばれてたのか?
SceneDelegateで最初の画面を出す
その答えはSceneDelegate
です。
まず、Info.plist
のApplication Scene Manifest
にて、SceneDelegate
がデフォルトで指定されています。
このためアプリ起動時、SceneDelegate
の以下部分が呼ばれます。
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
を継承したカスタムクラスを用意して、
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を使いたい場合、
struct TextView: UIViewRepresentable {
@Binding var text: String
func makeUIView(context: Context) -> UITextView {
return UITextView()
}
func updateUIView(_ uiView: UITextView, context: Context) {
uiView.text = text
}
}
こんなクラスを作って、生成時と更新時の処理を書きます。利用側では、
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
には、デフォルトで以下の記述があります。
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
ここにプレビューしたいViewを書いておくと、Xcodeが自動で見つけてプレビュー対象にしてくれます。
プロジェクト構成まとめ
SwiftUIに必要なものは以下です。
・Info.plist
のApplication Scene Manifest
定義
・SceneDelegate
・UIHostingController
のrootView
に渡すView
・プレビューしたい場合PreviewProvider
最後に
次回はSwiftUIで簡単に実装できる何らかのレイアウトを紹介します。
従来と比べてどれくらい簡単になるかを体験しましょう!
で、1日目すっかり忘れてたんですが、これは「4泊5日のGW旅行」なので、グルメ写真も載せます。
お昼は松島町の「さんとり茶屋」さんで穴子丼をいただきました😋
夜は旅行の定番、懐石料理。さぁ乾杯!!
※写真は2017年GW旅行のものです