An easy way to handle dismissal in modal presentation

Updated
Dec 17, 2020 5:16 AM
Created
Dec 17, 2020 5:06 AM
Tags
SwiftUIKit
Keywords
Date

extension UIViewController {

  @available(iOS 13.0, *)
  private final class _AdaptivePresentationControllerDelegate: NSObject, UIAdaptivePresentationControllerDelegate {

    var onDidDismiss: () -> Void = {}

    @available(iOS 13.0, *)
    func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
      onDidDismiss()
    }
  }

  /**
   Registers a callback closure that performs on itself dismissed.

   - Warning:
   This method replaces UIAdaptivePresentationControllerDelegate of its presentation-controller inside.
   If you're using a custom delegate, you can't use this method.
   */
  @available(iOS 13.0, *)
  public func registerDidDismissUsingAdaptivePresentationControllerDelegate(_ onDidDismiss: @escaping () -> Void) {

    let delegate = _AdaptivePresentationControllerDelegate()

    delegate.onDidDismiss = {
      onDidDismiss()

      /// In order to retain until dismissed since UIPresentationController.delegate won't retain it.
      withExtendedLifetime(delegate) {}
    }

    presentationController!.delegate = delegate
  }

}