David Seek David Seek - 1 month ago 9
iOS Question

Swift 3 / Why does the snapshot from snapshotView appears blank in iPhone 7 Plus Simulator?

I'm using the following code to create a custom Menu transition. I have spent the last two hours trying to figure out, why the snapshot appears blank (using the iPhone 7 Plus simulator only). But when I wanted to create a video to make it into a gif for this thread, it worked on my iPhone 6S Plus.

Update: Works on iPhone 6S Simulator as well. But still not in 7 Plus.

import UIKit

class PresentMenuAnimator : NSObject {
}

extension PresentMenuAnimator : UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.6
}

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
let containerView = transitionContext.containerView
containerView.insertSubview((toVC?.view)!, belowSubview: (fromVC?.view)!)

// replace main view with snapshot
let snapshot = fromVC?.view.snapshotView(afterScreenUpdates: false)
snapshot?.tag = MenuHelper.snapshotNumber
snapshot?.isUserInteractionEnabled = false
snapshot?.layer.shadowOpacity = 0.7
containerView.insertSubview(snapshot!, aboveSubview: (toVC?.view)!)
fromVC?.view.isHidden = true

UIView.animate(
withDuration: transitionDuration(using: transitionContext),
animations: {
snapshot!.center.x += UIScreen.main.bounds.width * MenuHelper.menuWidth
},
completion: { _ in
fromVC?.view.isHidden = false
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
)
}
}


iPhone 6S Plus (physical device) iOS 10

enter image description here

iPhone 7 Plus (simulator) iOS 10

enter image description here

enter image description here

Why is the snapshot on the simulator blank?

GitHub test project

Answer

Add this UIView extension,

public extension UIView {
    public func snapshotImage() -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0)
        drawHierarchy(in: bounds, afterScreenUpdates: false)
        let snapshotImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return snapshotImage
    }

    public func snapshotView() -> UIView? {
        if let snapshotImage = snapshotImage() {
            return UIImageView(image: snapshotImage)
        } else {
            return nil
        }
    }
}

Update your following code,

let snapshot = fromVC?.view.snapshotView(afterScreenUpdates: false)

with,

let snapshot = fromVC?.view.snapshotView()

Ref

Comments