ひとしれずひっそり

主にソフトに関することをメモしていきます。過程をそのまま書いていたりするので間違いが含まれます。鵜呑みしない様に。

SwiftUIでModal ViewがBackgroundになった時に通知させる

scenePhaseを使うとバックグラウンドになった時に通知されるのだが、Modal Viewが表示されているときは呼び出されなかった。

struct MessageView: View {
    @Environment(\.scenePhase) private var scenePhase
    @Binding var isPresented: Bool
    var body: some View {
        Text("バックグラウンドになると閉じます.")
            .onChange(of: scenePhase) { newPhase in
                switch(newPhase) {
                case .inactive, .background:
                    isPresented = false
                default:
                    break
                }
            }
    }
}

struct ContentView: View {
    @State var isPresented = false
    
    var body: some View {
        VStack {
            Button("メッセージ表示") {
                isPresented = true
            }
        }
        .fullScreenCover(isPresented: $isPresented) {
            MessageView(isPresented: $isPresented)
       }
        .padding()
    }
}

恐らくscenePhaseはWindow毎にEnvironment属性でセットされていてModal Viewではセットされていないのだろう。

Modal ViewにscenePhaseを渡して通知される様になった。

struct ContentView: View {
    @Environment(\.scenePhase) private var scenePhase
    @State var isPresented = false
    
    var body: some View {
        VStack {
            Button("メッセージ表示") {
                isPresented = true
            }
        }
        .fullScreenCover(isPresented: $isPresented) {
            MessageView(isPresented: $isPresented)
                .environment(\.scenePhase, scenePhase)
      }
        .padding()
    }
}

MessageView()を表示してから、Home画面にもどると元の画面に戻っている。