Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a SwiftUI equivalent for viewWillDisappear(_:) or detect when a view is about to be removed?

In SwiftUI, I'm trying to find a way to detect that a view is about to be removed only when using the default navigationBackButton. Then perform some action.

Using onDisappear(perform:) acts like viewDidDisappear(_:), and the action performs after another view appears.

Or, I was thinking the above problem might be solved by detecting when the default navigationBarBackButton is pressed. But I've found no way to detect that.

Is there any solution to perform some action before another view appears?

(I already know it is possible to do that by creating a custom navigation back button to dismiss a view)

like image 348
FRIDDAY Avatar asked Jan 15 '20 05:01

FRIDDAY


1 Answers

Here is approach that works for me, it is not pure-SwiftUI but I assume worth posting

Usage:

   SomeView()    .onDisappear {         print("x Default disappear")     }    .onWillDisappear { // << order does NOT matter         print(">>> going to disappear")     } 

Code:

struct WillDisappearHandler: UIViewControllerRepresentable {     func makeCoordinator() -> WillDisappearHandler.Coordinator {         Coordinator(onWillDisappear: onWillDisappear)     }      let onWillDisappear: () -> Void      func makeUIViewController(context: UIViewControllerRepresentableContext<WillDisappearHandler>) -> UIViewController {         context.coordinator     }      func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<WillDisappearHandler>) {     }      typealias UIViewControllerType = UIViewController      class Coordinator: UIViewController {         let onWillDisappear: () -> Void          init(onWillDisappear: @escaping () -> Void) {             self.onWillDisappear = onWillDisappear             super.init(nibName: nil, bundle: nil)         }          required init?(coder: NSCoder) {             fatalError("init(coder:) has not been implemented")         }          override func viewWillDisappear(_ animated: Bool) {             super.viewWillDisappear(animated)             onWillDisappear()         }     } }  struct WillDisappearModifier: ViewModifier {     let callback: () -> Void      func body(content: Content) -> some View {         content             .background(WillDisappearHandler(onWillDisappear: callback))     } }  extension View {     func onWillDisappear(_ perform: @escaping () -> Void) -> some View {         self.modifier(WillDisappearModifier(callback: perform))     } } 
like image 191
Asperi Avatar answered Sep 18 '22 18:09

Asperi