Home > Net >  Run action when view is 'removed'
Run action when view is 'removed'

Time:06-23

I am developing an app which uses UIKit. I have integrated a UIKit UIViewController inside SwiftUI and everything works as expected. I am still wondering if there is a way to 'know' when a SwiftUI View is completely gone.

My understanding is that a @StateObject knows this information. I now have some code in the deinit block of the corresponding class of the StateObject. There is some code running which unsubscribes the user of that screen.

The problem is that it is a fragile solution. In some scenario's the deinit block isn't called.

Is there any recommended way to know if the user pressed the back button in a SwiftUI View (or swiped the view away)? I don't want to get notified with the .onDisppear modifier because that is also called when the user taps somewhere on the screen which adds another view to the navigation stack. I want to run some code once when the screen is completely gone.

CodePudding user response:

Is there any recommended way to know if the user pressed the back button in a SwiftUI View (or swiped the view away)?

This implies you're using a NavigationView and presenting your view with a NavigationLink.

You can be notified when the user goes “back” from your view by using one of the NavigationLink initializers that takes a Binding. Create a custom binding and in its set function, check whether the old value is true (meaning the child view was presented) and the new value is false (meaning the child view is now being popped from the stack). Example:

struct ContentView: View {
    @State var childIsPresented = false
    @State var childPopCount = 0

    var body: some View {
        NavigationView {
            VStack {
                Text("Child has been popped \(childPopCount) times")
                NavigationLink(
                    "Push Child",
                    isActive: Binding(
                        get: { childIsPresented },
                        set: {
                            if childIsPresented && !$0 {
                                childPopCount  = 1
                            }
                            childIsPresented = $0
                        }
                    )
                ) {
                    ChildView()
                }
            }
        }
    }
}

struct ChildView: View {
    var body: some View {
        VStack {
            Text("Sweet child o' mine")

            NavigationLink("Push Grandchild") {
                GrandchildView()
            }
        }
    }
}

struct GrandchildView: View {
    var body: some View {
        VStack {
            Text("           
  • Related