1
votes

I am trying to present a view controller modally. It is like a pop up view controller.

I am using animateTransition method to animate the transition. This is my code:

extension PopUpViewController: UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning {

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.25
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        guard let fromVC = transitionContext.viewController(forKey: .from) else { return}
        guard let toVC = transitionContext.viewController(forKey: .to) else { return}
        guard let fromView = transitionContext.view(forKey: .from) else { return}
        guard let toView = transitionContext.view(forKey: .to) else { return}

        var containerView = transitionContext.containerView

        if toVC == self {
            // presenting
            containerView.addSubview(toView)
            toView.frame = fromView.frame
            popUpView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
            toView.alpha = 0
            UIView.animate(withDuration: 0.25, animations: {
                toView.alpha = 1
                self.popUpView.transform = CGAffineTransform.identity
            }) { _ in

                DispatchQueue.main.async {
                    transitionContext.completeTransition(true)
                }
            }
        } else {
            // dismissing
            UIView.animate(withDuration: 0.25, animations: {
                self.popUpView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
                fromView.alpha = 0
            }) { _ in
                transitionContext.completeTransition(true)
            }
        }
    }

    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self
    }
}

I am presenting this view controller (Presented VC) over the other view controller(Presenting VC) in this way. I am using the default modal presentation style. Initially I was using custom but I looked at some posts on StackOverflow and they said to remove it but still, I am getting a black screen(presenting VC) and I can see the presented VC over it.

When I am dismissing the presented VC, again the presenting VC is visible.

Please do let me know in case you need more details.

As per code when transitionContext.completeTransition(true) is executed, presenting VC screen turns black

2
Please read minimal reproducible example and then edit your question showing the minimum code that demonstrates the problemAshley Mills
I have removed the extra codeSudhanshu Gupta

2 Answers

2
votes

You can try your pop-over viewController's modalPresentationStyle to either .overCurrentContext or .overFullScreen.

case overCurrentContext:

A presentation style where the content is displayed over another view controller’s content.

This means it will present the next viewController over the viewController's content.

So in case of Container ViewControllers:

So if you have any tabBarController, the tabBar will allow user to interact with it.

case overFullScreen

A view presentation style in which the presented view covers the screen.

This means it will present next viewController over the fullScreen so the taBar will not be interactive till the presentation finish.

func presentNextController() {
    // In case your viewController is in storyboard or any other initialisation
    guard let nextVC = storyboard.instantiateViewController(with: "nextVC") as? NextViewController else { return }

    nextVC.modalPresentationStyle = .overFullScreen
    // set your custom transitioning delegate

    self.present(nextVC, animated: true, completion: nil)
}
1
votes

You need to set your new view controller's

modalPresentationStyle = .overCurrentContext

Do this when you initialise your view controller, or in the storyboard.