0

I'm doing a custom view controller transition in which the presented view controller, detailVC, is scaled down when dismissed.

The procedure I chose is the following:

  1. snapshot detailVC.view, add it to the transition context's containerView
  2. hide detailVC.view
  3. scale down the snapshot.

Here's the code:

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

    let detailVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as? DetailViewController

    containerView.addSubview(detailVC.view)
    detailVC.view.frame = containerView.frame

    let detailVCSnapshot = detailVC.view.snapshotViewAfterScreenUpdates(true)
    containerView.addSubview(detailVCSnapshot)

    detailVC.view.hidden = true
    ...
}

Bizarrely, this works well on the iPad, but not on iPhone. On iPhone, detailVCSnapshot is completely transparent.

Other answers (1, 2) recommend ensuring that the view has been drawn, but this is indeed the case as detailVC is the currently visible view controller!

Any thoughts?

Community
  • 1
  • 1
Eric
  • 16,003
  • 15
  • 87
  • 139

1 Answers1

1

I found a workaround involving using UIGraphicsGetImageFromCurrentImageContext on iPhone:

let detailVCSnapshot = isIphone ? UIImageView(image: detailVC.view.snapshotImage) : detailVC.view.snapshotViewAfterScreenUpdates(true)

private extension UIView {
    var snapshotImage: UIImage {
        UIGraphicsBeginImageContextWithOptions(bounds.size, true, 0)
        layer.renderInContext(UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

Any explanations or alternatives would be welcome!

Eric
  • 16,003
  • 15
  • 87
  • 139
  • This solution is unfortunately incredibly slower if you have lots of CALayer elements rendering. The other solution is lightning fast but seems to only work on some devices, very strange! – Albert Renshaw Jul 14 '20 at 01:52