SwiftUI 振舞い編(2) 画面遷移への準備

SwiftUI

では、さっそくボタンが押されたら、画面遷移するように書こう!とおもって、ハタと気付きました。どうやるの?UIKitなら、present(ViewController)みたいな感じで、画面遷移させられたのですが、SwiftUIでは??

遷移先の画面

どうやって遷移するかも大事だけど、遷移先も大事です。作ってませんでしたので、とりあえず、真ん中にテキストが置いてある画面をConfigViewなる名前で作成しました。

SwiftUIでの画面遷移

struct ConfigView: View {
    var body: some View{
        Text("Config view")
    }
}

このままでは、Simulator起動しても表示する術がないので、Portrait画面に対応していないとはいえ、Previewで確認しないといけません。(自信があれば、不要かもですが)
なので、ContentView_Previewsの中をちょっと書き換えて、Previewで確認しましょう。こんな感じです。

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        // ContentView()
        ConfigView()
    }
}

PreviewはLandscape対応していないので、Portraitで確認したものがきちんとLandscapeでも表示されることを祈って確認は終わりとしました。

いよいよ遷移!

ぜんかい、そのためにButtonを貼り付けておいたのですが、調べてみたところ、NavigationLinkというものを使うらしいです。(いつか、ボタンを使いたい時のための練習だったということで)

NavigationLink#init(_ titleKey: LocalizedStringKey, destination: Destination)

上記のInitializerを使うのがシンプルで良さげ。引数的には、前回のButtonと似てますよね。最初は、表示されるテキストで、Buttonではactionだったところが、遷移先を書くようになってます。

Destinationて何?

UIKitでは、遷移先のViewControllerが全てでしたが、NavigationLinkで渡す、Destinationとはなんでしょうか?
Structureの説明をきちんと読んだら、Destination: Viewとなってました。つまり、Viewを渡せば良いはずです。さっき作ったConfigViewもViewなので、渡せば良いっぽいです。ラッキー!

渡してみました

var body: some View {
    VStack(){
        Image(systemName: "pencil").resizable().scaledToFit()
        HStack() {
            AdBanner(adUnitId: "ca-app-pub-XXX/XXXX").expectedFrame() // test id
            NavigationLink.init("ConfigView", destination: ConfigView())

        }
    }
}

動きません・・・orz というか、リンクがアクティブになっていない感じ。Apple様のドキュメントではなく、Google様に聞いてみたところ、NavigationLinkはNavigationViewと定義されたViewからでないと動作しないとのこと。

NavigationView

慌てて、メインの方のビューをNavigationViewにしてみたのが、以下。

  var body: some View {
    NavigationView{
      VStack(){
        Image(systemName: "pencil").resizable().scaledToFit()
        HStack() {
          // AdBanner(adUnitId: "ca-app-pub-7219436282372946/1269091045")// real id
          AdBanner(adUnitId: "ca-app-pub-3940256099942544/2934735716").expectedFrame() // test id
          NavigationLink.init("ConfigView", destination: ConfigView())
          
        }
      }.navigationViewStyle(StackNavigationViewStyle())
    }
  }

動きました

こんなにコードを書いていないのに、イメージビューがあって、広告貼ってあって、ボタン(のように見えるもの)を押すことで別画面に遷移できるようになりました。

注意
NavigationLinkで作られるBack Buttonには、バグがあるらしくて、Simulatorで動かすと、2回目以降で遷移しなくなります。
このバグを回避するために、Buttonを使って遷移させることになります。それは、次回に説明します。

LandscapeモードだとNavigationViewが非常に不安定というか、一部オプションに不具合があるらしく、NavigationViewにnavigationViewStyle(StackNavigationViewStyle())と追加しないと画面が白くなってしまいます。
上のコードは対応済みです。SwiftUI周りは、すこしBuggyですね。これは、大きな画面を持つ(私は、iPhone11 Pro Maxで試してました)ケースだとDetailViewを表示しようとして起こるみたいです。画面の小さい機種、例えば、iPhone8だと上記のmodifierを付加しなくて表示されます。もう少し調査が必要ですね。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です