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("