SwiftUI Tutorials: 8日目
最終回「Interface with UIKit」。
- UIViewControllerはUIViewControllerRepresentableに適合したクラスでwrap
- makeUIViewController(context:) -> UIViewController で画面インスタンスの初期化を行う
- UIViewControllerが要するdelegate/data sourceは、UIViewControllerRepresentable.Coordinatorに実装する (makeCoordinator() -> Coordinator)
- makeUIViewController(context:)よりも先に呼ばれるので、view controllerの各種設定にcontext(Coordinator)を使うことができる
- delegate, data sourceに加えて、target-actionを用いたユーザーイベントへの応答も、Coordinatorへ実装する(この場合Cocoaパターンを使用するため、親クラスはNSObjectとする)
- updateUIViewController(context:)への実装により、最新のcontextに応じて表示内容の更新をする
- @Binding プロパティを定義し
- この変更と同期してupdateUIViewController…が呼び出される
- 外部インスタンスの@Stateのbindingを初期化時に渡すことで、状態を同期することができる(チュートリアルでは、PageViewのもつ@State pageIndexを、PageControlとPageViewControllerのそれぞれが持つ@Binding pageIndexにbindingして、ページング表示を同期する)
- @Binding プロパティを定義し
- UIViewControllerRepresentableのbodyへの配置は、Viewと同様に初期化して並べるだけ
- UIView(UIControl)をUIViewRepresentableに適合したクラスでwrapして、カスタムコントロールを実装することができる
- makeUIView(context:) -> UIView でビューインスタンスの初期化を行う
- UIViewControllerRepresentableと同様に、UIViewRepresentable.Coordinator に、Cocoaを用いる処理を委譲する(UIControlのtarget-actionパターン)
サンプルコードの実装をそのまま実行しただけでは、チュートリアルの示す画面が表示されなかった。SceneDelegateでのルート画面指定がCategoryHome()のままだったので、PageView(features.map { FeatureCard(landmark: $0) })に置き換えたらうまくいった。
加えて、PageControlの表示位置もチュートリアル通りではない。PageViewControllerが画面縦いっぱいに広がっているので、.bottomTrailingで整列させたpage controlは、写真のはるか下、画面の最下に実は存在しているのだった。しかもpage controlが画面背景と同色の白色なので、まるで表示されてないかのように見えるのもタチが悪い笑
これは、以下のようにZStackをVStackに内包させ、上下をSpacerで挟むことにより簡単に解決できる。
VStack { Spacer() ZStack(alignment: .bottomTrailing) { ... } Spacer() }
さて、SwiftUI Tutorialsはこれで完遂した。数日で終わるかと思いきや、だらだらと2週間もかけてしまった。
現状では、チュートリアルやサンプルコードに誤りが多いので、まったくの初学者が始めると、こうした混乱に陥って却って挫折してしまうかもしれない笑 もちろん、秋の正式リリースには全て修正されるだろうし、チュートリアルのコンテンツも今後充実してくるかもしれない。