How to achieve such a modal window effect? When the active view goes to the background and the modal window does not go to the full height of the screen

  • Well, the modal window just does not fit. Try either to add your view directly to controller.view, or you can try to create another UIWindow and do it all on it. - Max Mikheyenko

1 answer 1

Perhaps not quite as in the mail, slightly redid the existing option.

Here is the source code of the example and the gif demo on GitHub

Result:

enter image description here

Now in order:

1 Extension for the controller from where:

 extension ViewController: UIViewControllerTransitioningDelegate { func animationController( forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { transition.presenting = true transition.duration = 0.5 return transition } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { transition.presenting = false return transition } } 

2 Switch to 2 controllers:

 let secondViewController = storyboard!.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController secondViewController.transitioningDelegate = self secondViewController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext present(secondViewController, animated: true, completion: nil) 

3 UIViewControllerTransitioningDelegate protocol for the second controller:

 class SecondViewController: UIViewController, UIViewControllerTransitioningDelegate { 

4 class with the necessary animation:

 import UIKit class TransitionMailLikeAnimator: NSObject, UIViewControllerAnimatedTransitioning { var duration = 0.6 var presenting = true func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?)-> TimeInterval { return duration } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)! let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)! let toView = toViewController.view let containerView = transitionContext.containerView if presenting { containerView.addSubview(toView!) } let bottomViewController = presenting ? fromViewController : toViewController let bottomPresentingView = bottomViewController.view let topViewController = presenting ? toViewController : fromViewController let topPresentedView = topViewController.view var topPresentedFrame = transitionContext.finalFrame(for: topViewController) if presenting { topPresentedFrame = CGRect(x: 0, y: 38, width: topPresentedFrame.width, height: topPresentedFrame.height - 38) } var topDismissedFrame = topPresentedFrame topDismissedFrame.origin.y += topDismissedFrame.size.height let topInitialFrame = presenting ? topDismissedFrame : topPresentedFrame let topFinalFrame = presenting ? topPresentedFrame : topDismissedFrame topPresentedView?.frame = topInitialFrame UIView.animate(withDuration: duration, animations: {() -> Void in topPresentedView?.frame = topFinalFrame let scalingFactor: CGFloat = self.presenting ? 0.91 : 1.0 bottomPresentingView?.transform = CGAffineTransform.identity.scaledBy(x: scalingFactor, y: scalingFactor) }, completion: {(finished: Bool) -> Void in transitionContext.completeTransition(true)}) } }