7

I have fully transparent a table and navigation controllers. Because of this, when pushing new view controllers the animation was broken. Therefore I added my own custom push transition which takes snapshot of the next view controller and animates that.

This no longer works on iOS10. snapshotView(afterScreenUpdates: true) returns a view that is pure white. I also tried getting the snapshot with the old method through graphics context and it didn't work too.

How can I be sure that the view being pushed to the navigation controller is loaded before snapshotView? Or is there a better way to solve this? This is a breaking change for me unfortunately..

frankish
  • 6,738
  • 9
  • 49
  • 100
  • I'm wondering how that ever could worked. You take a snapshot of a view, before it got visible. Can you explain a bit more in detail? Where exactly do you do the snapshot? How do you do the transition and of course: does your first problem with the messed up transition still exist? – jboi Sep 18 '16 at 11:01
  • 1
    I am seeing the same thing on iPhone 7 (or 7 Plus) Simulators only. Other simulators and devices seem unaffected. – Keller Sep 22 '16 at 20:49
  • Same thing happens on both Device (iPhone 6S) and Simulator on iOS 13. I had to use proposed `snapshotImageView()` method instead. – Borzh Dec 03 '20 at 19:37

2 Answers2

8

I want to just say that this is strictly an iPhone 7 simulator and iPhone 7+ simulator issue. The issue will not appear on a real device. If you need to fix this for the simulator here is a work around I found in Pod: https://github.com/NewAmsterdamLabs/ZOZolaZoomTransition/

- (UIImage *)zo_snapshot {
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, [UIScreen mainScreen].scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [self.layer renderInContext:context];
    UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return snapshot;
}
Ryan Heitner
  • 13,119
  • 6
  • 77
  • 119
HannahCarney
  • 3,441
  • 2
  • 26
  • 32
  • 1
    I beileve you mean iPhone 7 and iPhone 7+ simulator. The same issue occurred for me where the snapshot view was not working as expected for those simulators. Switching to a different simulator fixed the issue. Wierd. – Idr Jan 03 '17 at 19:04
2

This extension should fix the issue

extension UIView {
    /// Replacement of `snapshotView` on iOS 10. Fixes the issue of `snapshotView` returning a blank white screen.
    func snapshotImageView() -> UIImageView? {
        UIGraphicsBeginImageContext(bounds.size)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }

        layer.render(in: context)

        let viewImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return UIImageView(image: viewImage, highlightedImage: viewImage)
    }
}
Bebekucing
  • 383
  • 4
  • 12
  • This seems it may work but it's visual quality is very bad. I tried to do this but it didn't work : `let scale = self.contentScaleFactor; context.scaleBy(x: scale, y: scale);` – frankish Sep 21 '16 at 21:42
  • @frankish Can you try replacing `UIGraphicsBeginImageContext(bounds.size)` with `UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0)`. Let me know if it improves the quality. – Bebekucing Sep 21 '16 at 22:04
  • Unfortunately I found out that this code block does not solve it. At first, I thought that it solved it but it seems like I was keeping my delayed processing hacks.. When I cleaned my hacks, it still shows black.. My hack is: I add the upcoming view to the screen. I take snapshot of it and remove it after `DispatchQueue.main.asyncAfter 0.1ms` later. So it allows time to it to draw render itself :/ – frankish Sep 22 '16 at 11:31
  • Answering a question by just telling the OP to use a completely different API without explaining why isn't ideal. It would be nice to understand exactly whats different and why you recommended this approach – Daniel Galasko Oct 25 '16 at 15:15