3

I have been using the following method in my custom Animator class for a transition when a user selects a imageView in a cell of a tableViewController to a focus view showing the enlarged image. The imageView animates nicely from it's frame in the tableView to full screen and then back when I dismiss it.

This worked fine prior to iOS 13. But now when I use this animated transition on a modally presented tableViewController, the animation to the focus view works fine but when I dismiss the focus view to animate back to the tableViewController, the tableViewController is no longer there. It just shows the greyed out viewController that was underneath the modally presented tableViewController. I know the new modalPresentation default style is pageSheet but not sure why the top view controller prior to the animation disappears?

The animation still works fine for viewControllers that are not modally presented.

Wonder if this is a bug or if anybody has found a solution?

Here is my animateTransition function:

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    // define variable to keep track of whether transitioning from or to
    var presentingImage = false

    // define containerView
    let containerView = transitionContext.containerView

    // get view controllers
    let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
    let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!

    // set the destination view controllers frame
    toVC.view.frame = fromVC.view.frame

    // create transition imageView
    let imageView = UIImageView(image: image)
    imageView.contentMode = .scaleAspectFill
    imageView.frame = (fromDelegate == nil) ? CGRect() : fromDelegate!.imageWindowFrame()
    imageView.clipsToBounds = true

    // add imageView to containerView
    containerView.addSubview(imageView)

    // create from screen snapshot
    fromDelegate!.transitionSetup(presentingImage: presentingImage)
    toDelegate!.transitionSetup(presentingImage: presentingImage)
    let fromSnapshot = fromVC.view.snapshotView(afterScreenUpdates: true)!
    fromSnapshot.frame = fromVC.view.frame
    containerView.addSubview(fromSnapshot)

    // create to screen snapshot
    let toSnapshot = toVC.view.snapshotView(afterScreenUpdates: true)!
    toSnapshot.frame = fromVC.view.frame
    containerView.addSubview(toSnapshot)
    toSnapshot.alpha = 0

    // bring the image view to the front and get the final frame
    containerView.bringSubviewToFront(imageView)
    let toFrame = (self.toDelegate == nil) ? CGRect() : self.toDelegate!.imageWindowFrame()

    // animate change
    UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.8, options: .curveEaseOut, animations: {

        // set toSnapshot alpha to 1
        toSnapshot.alpha = 1

        // set imageView frame to toFrame
        imageView.frame = toFrame

    }, completion:{ (finished) in

        // call transition cleanup for to and from delegate
        self.toDelegate!.transitionCleanup(presentingImage: presentingImage)
        self.fromDelegate!.transitionCleanup(presentingImage: presentingImage)

        // remove transition views
        imageView.removeFromSuperview()
        fromSnapshot.removeFromSuperview()
        toSnapshot.removeFromSuperview()

        // complete transition
        if !transitionContext.transitionWasCancelled {
            containerView.addSubview(toVC.view)
        }
        transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    })
}
alionthego
  • 8,508
  • 9
  • 52
  • 125
  • I had same issue with iOS 13, the animator that was working before broke. If the toVC is presented not in full screen, then I can see the fromVC is shrunk and lies behind the toVC, however, when the the toVC is presented in full screen, when I dismiss the toVC, the fromVC is pitch black, then about a second, the content will resume – infinity_coding7 Nov 13 '19 at 03:23
  • I don't have the content resuming after a second. it just stays black and I have to quit the app. let me know if you find a fix. – alionthego Nov 13 '19 at 08:47

2 Answers2

0

The answer above is correct to set modalPresentationStyle to .fullScreen, however it is also worth to mention that if your view controller is embedded in a UINavigationController, you need to set it on the view controller:

viewController.modalPresentationStyle = .fullScreen
Word Rearranger
  • 1,306
  • 1
  • 16
  • 25
0

It's a late replay but I think you should try the way I am doing it.

Code for presenting view -

  let cardsScreen: SideMenuController = SideMenuController(nibName: "SideMenuController", bundle: nil)
  cardsScreen.modalPresentationStyle = .fullScreen
  self.navigationController?.present(cardsScreen, animated: true, completion: nil)

As in my case SideMenuController is a ViewController in which I am adding animation on Table.

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cell.transform = CGAffineTransform(translationX: cell.contentView.frame.width, y: 0)
    UIView.animate(withDuration: 0.5, delay: 0.05 * Double(indexPath.row), usingSpringWithDamping: 0.4, initialSpringVelocity: 0.1,
    options: .curveEaseIn, animations: {
    cell.transform = CGAffineTransform(translationX: cell.contentView.frame.width, y: cell.contentView.frame.height)
    })
}

And it's working pretty good.