onDisappear not called when a modal View is dismissed

假如想象 提交于 2020-04-16 02:26:13

问题


I rely on the SwiftUI's .onDisappear to perform some logic but it is not being called when the user dismisses a modally presented view with the swipe gesture. To reproduce

  • Present a view modally a "ChildView 1"
  • On this view, push a "ChildView 2" as a navigation child
  • Swipe down to dismiss the modal view.

The .onDisappear of "ChildView 2" is not called.

Sample code to reproduce

import SwiftUI

struct ContentView: View {
    @State var isShowingModal
    var body: some View {
        NavigationView {
            Button(action: {
                self.isShowingModal.toggle()
            }) {
                Text("Show Modal")
            }
        }
        .sheet(isPresented: $isShowingModal) {
            NavigationView {
                ChildView(title: 1)
            }
        }
    }
}

struct ChildView: View {
    let title: Int
    var body: some View {

        NavigationLink(destination: ChildView(title: title + 1)) {
            Text("Show Child")
        }
        .navigationBarTitle("View \(title)")


        .onAppear {
            print("onAppear ChildView \(self.title)")
        }
        .onDisappear {
            print("onDisappear ChildView \(self.title)")
        }
    }
}

The output is:

onAppear ChildView 1
onAppear ChildView 2
onDisappear ChildView 1


回答1:


If you're looking for logic to occur when the actual modal is dismissed, you're going to want to call that here, where I print out Modal Dismissed:

struct ContentView: View {
    @State var isShowingModal = false
    var body: some View {
        NavigationView {
            Button(action: {
                self.isShowingModal.toggle()
            }) {
                Text("Show Modal")
            }
        }
        .sheet(isPresented: $isShowingModal) {
            NavigationView {
                ChildView(title: 1)
            }
            .onDisappear {
                print("Modal Dismissed")
            }
        }
    }
}



回答2:


struct ContentView: View {
    @State var isShowingModal = false
    var body: some View {
        NavigationView {
            Button(action: {
                self.isShowingModal.toggle()
            }) {
                Text("Show Modal")
            }
        }
        .sheet(isPresented: $isShowingModal) {
            NavigationView {
                ChildView(title: 1)
            }
        }
    }
}

in this code, you have NavigationView, and when presenting sheet, you push there another NavigationView. This is the source of trouble

You don't need any NavigationView to present modals. If you like to present another modal from modal, you can use

import SwiftUI

struct ContentView: View {
    var body: some View {
         ChildView(title: 1)
    }
}

struct ChildView: View {
    @State var isShowingModal = false
    let title: Int
    var body: some View {

        Button(action: {
                self.isShowingModal.toggle()
            }) {
                Text("Show Modal \(title)").font(.largeTitle)
            }
        .sheet(isPresented: $isShowingModal) {
            ChildView(title: self.title + 1)

        }
    }
}

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

UPDATE

from Apple Human Interface Guidelines

Modality is a design technique that presents content in a temporary mode that’s separate from the user's previous current context and requires an explicit action to exit



来源:https://stackoverflow.com/questions/60468040/ondisappear-not-called-when-a-modal-view-is-dismissed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!