見出し画像

わからないコードも瞬時に解決!複数モーダルを一度に閉じる方法をChatGPTに教えてもらった(swiftUI, iPhoneアプリ)

ナビゲーション遷移とモーダル遷移を合わせ技で画面遷移を実装したところ、遷移が上手くいかず・・!
そもそもモーダル画面の表示制御があまりわかっていなかったので、まずはモーダル遷移の制御について、整理してみることにしました。

この記事では、モーダル遷移で画面を複数表示し(複数被せて)、その後複数のモーダルを一度に閉じる方法をChatGPTに教えてもらったので、その内容をまとめました。

以前、ナビゲーション遷移をChatGPTに教えてもらった際の記事

複数のモーダルを同時に閉じる方法

複数のモーダルを同時に閉じる方法は以下で、ChatGPTにレクチャーしてもらった内容のまとめから入ります。
(実際にChatGPTとのやりとりは後述。)

やりたいことイメージ

モーダルの表示制御は、Boolの変数で制御

@State private var showModalB = false

・・・省略・・・
.sheet(isPresented: $showModalB) { // Bool変数を監視し、モーダルを制御
    ViewModalB(isPresented: $showModalB) 
}

モーダル制御変数を次のモーダルにも引き回し、複数の変数をfalseにできるようにする

ViewModalBへ遷移する際に、モーダル制御変数を渡す

struct ContentView: View {
  @State private var showModalB = false
  ・・・省略・・・
  .sheet(isPresented: $showModalB) { 

      // ViewModalBモーダルの制御変数を渡す
      ViewModalB(isPresented: $showModalB) 
  }
}

@Bindingで変数を受け取り、ViewModalBへ遷移する際に、ViewModalB,Cモーダルの制御変数を渡す

struct ViewModalB: View {

  // ViewModalBモーダルの制御変数を受け取る
  @Binding var isPresented: Bool 
  @State private var showModalC = false

  .sheet(isPresented: $showModalC) {
        // ViewModalB,Cモーダルの制御変数を渡す
        ViewModalC(isPresented: $showModalC, parentPresentation: $isPresented)
    }
}

ChatGPTに複数のモーダルを同時に閉じる方法を教えてもらう

順番は前後してしまいましたが、ChatGPTにレクチャーしてもらった内容は以下となります。

プロンプト

swiftUI
viewAからViewModalBをモーダルで表示
ViewModalBからViewModalCをモーダルで表示
ViewModalCにて、閉じるボタンを押下すると、ViewModalC、ViewModalBを閉じる

ChatGPTの回答

SwiftUIで指定された動作を実現するには、@Stateや@Environment、@Bindingを使って表示状態を管理し、閉じるボタンを押下した際に親のビューまで閉じることができます。以下にその実装例を示します。

import SwiftUI

struct ViewA: View {
    @State private var showModalB = false

    var body: some View {
        VStack {
            Text("ViewA")
            Button("Show Modal B") {
                showModalB = true
            }
        }
        .sheet(isPresented: $showModalB) {
            ViewModalB(isPresented: $showModalB)
        }
    }
}
import SwiftUI

struct ViewModalB: View {
    @Binding var isPresented: Bool
    @State private var showModalC = false

    var body: some View {
        VStack {
            Text("ViewModalB")
            Button("Show Modal C") {
                showModalC = true
            }
        }
        .sheet(isPresented: $showModalC) {
            ViewModalC(isPresented: $showModalC, parentPresentation: $isPresented)
        }
    }
}
import SwiftUI

struct ViewModalC: View {
    @Binding var isPresented: Bool
    @Binding var parentPresentation: Bool

    var body: some View {
        VStack {
            Text("ViewModalC")
            Button("Close Both Modals") {
                isPresented = false
                parentPresentation = false
            }
        }
    }
}

この実装では、ViewAからViewModalBをモーダルで表示し、さらにViewModalBからViewModalCをモーダルで表示します。ViewModalCの閉じるボタンを押下すると、ViewModalCとViewModalBの両方が閉じられます。

ポイント
ViewModalBでは、isPresentedという@Bindingプロパティを使って親の表示状態を管理します。
ViewModalCでは、isPresentedとparentPresentationという2つの@Bindingプロパティを使って、自分自身と親の表示状態を管理します。
閉じるボタンを押下すると、両方の表示状態をfalseにすることで、両方のモーダルを閉じることができます。

おわりに

最後まで読んでいただき、ありがとうございます!

swiftUIの仕様をよくわかっていない状態で、ChatGTPに複雑な処理を依頼してしまうと、コードの内容が追えなくなってしまうので、まずは小さいスコープでのコーディング依頼をすると、挙動が整理しやすいですし、理解もしやすいのかなと思いました!

おまけ

最近、ChatGPTを使用し、色々なことを模索しています。
もしよければ、以下の記事も見て頂けると嬉しいです!

この記事が気に入ったらサポートをしてみませんか?