iosswiftuikituipresentationcontrollercustom-transition

Interrupting custom transition in the middle


While trying to implement custom transition animation, I stucked in interruption part. The thing I want to do is, by tapping dimmingView during transition, it should be cancelled and presented view controller dismised.

This is my dimming view:

class UIDimmingView: UIView {
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let hitView = super.hitTest(point, with: event)
        return hitView == self ? nil : hitView
    }
}

This is how I create and assign tap gesture recognizer to my dimming view:

lazy var dimmingView: UIDimmingView = {
    let view = UIDimmingView()

    view.backgroundColor = .black.withAlphaComponent(0.4)
    view.alpha = 0.0

    return view
}()
override func presentationTransitionWillBegin() {
    guard let containerView, let presentedView else { return }

    containerView.addGestureRecognizer(self.tapGesture)
    containerView.insertSubview(self.dimmingView, at: 0)

    self.dimmingView.fillSuperview()

    presentedView.layer.cornerRadius = 20.0
    presentedView.layer.cornerCurve = .continuous
    presentedView.layer.masksToBounds = true
}

And simply, onTap event, I do this:

@objc private func onTap(_ sender: UITapGestureRecognizer) {
    self.presentedViewController.dismiss(animated: true)
}

The final result looks like this.

I looked on Google, asked ChatGPT. However couldn't find a way to dismiss it in the middle of transitioning. How can I do it?


Solution

  • After searching through the internet, I found the cause of my issue. It was basically due to a non-interactive presentation style. If you want your "dimmingView" to respond to user interactions and be interruptable from the beginning, you should present your view controller interactively by providing the proper interactor class via:

    func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?
    

    Previously, I only made the dismissal interactive. So, it didn't get the gesture calls during the presentation.