QuickBirdEng / XCoordinator

🎌 Powerful navigation library for iOS based on the coordinator pattern
MIT License
2.27k stars 179 forks source link

Is there a way to dismiss a specific Presentable? #235

Closed SzymonWojcikCrustlab closed 1 year ago

SzymonWojcikCrustlab commented 2 years ago

I'm wondering if there is a way to dismiss a specific Presentable. Let's say I have NavigationController on which I have presented three different presentables (modals) in the following order: A -> B -> C

Later on I would like to dismiss B modal while A and C shouldn't be changed at all. (new stack: A -> B)

I was looking for something like this in the prepareTransition method

case .routeDismissB:
   let presentableB: UIViewController = // found in the current stack
   return .dismiss(presentableB)

Obviously, I can do something like that, but it would break the deep linking

case .routeDismissB:
   let presentableB: UIViewController = // found in the current stack
   presentableB.dismiss(animated: true)

   return .none()

Thank you in advance for any tips :)

pauljohanneskraft commented 1 year ago

There is no such transition, but you can easily build it yourself.

One such implementation would be:

extension Transition {

    static func dismiss(_ presentable: any Presentable, animation: Animation? = nil) -> Self {
         .init(presentables: [], animationInUse: animation?.dismissalAnimation) { _, options, completion in
             guard let presentedViewController = presentable.viewController else {
                  completion?()
                  return 
             }
             if let animation {
                 presentedViewController.transitioningDelegate = animation
             }
             presentedViewController.dismiss(animated: options.animated, completion: completion)
          }
     }

}

Normally, you should not need this and it might cause weird side-effects, which is why it is currently not part of XCoordinator.