Crop UIView Snapshot

I'm implementing a custom UINavigationViewController transition, and as part of the animation I want to snapshot and transform the destination UIViewController. However, I want to slice the snapshot and transform the parts independently.


There is a comment in UIView.h that seems to indicate that this is possible and even recommended:


Creating snapshots from existing snapshots (as a method to duplicate, crop or create a resizable variant) is supported. In cases where many snapshots are needed, creating a snapshot from a common superview and making subsequent snapshots from it can be more performant.


However, I cannot figure out how to actually do the cropping or create multiple snapshots from the common superview snapshot.


Is this possible?



Note: I did investigate using

UIView.drawHierarchy(in:afterScreenUpdates:)
to create an image that I can later crop, however this fails during a UINavigationController transition with the following error:

[Snapshotting] View (0x140853600, MTKView) drawing with afterScreenUpdates:YES inside CoreAnimation commit is not supported.

Accepted Reply

You don't grab entire and then crop:

- drawViewHierarchyInRect:afterScreenUpdates:

Renders a snapshot of the complete view hierarchy as visible onscreen into the current context.


...you spec a grab size/region based on insets:

- resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets:

Returns a snapshot view based on the specified contents of the current view, with stretchable insets.



Replies

You don't grab entire and then crop:

- drawViewHierarchyInRect:afterScreenUpdates:

Renders a snapshot of the complete view hierarchy as visible onscreen into the current context.


...you spec a grab size/region based on insets:

- resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets:

Returns a snapshot view based on the specified contents of the current view, with stretchable insets.



General recommendation is not to use image based snapshots (drawHierarchy and friends). They are slower, use more memory and have more sharp edges (more constrained in when you can do them, don't work with remote views, etc.). You only use image based snapshots when you have intention to save image to disk (which is not a good idea, because system settings might change, which will make snapshot obsolete). Thus, prefer using UIView based snapshots (snapshotViewAfterScreenUpdates and resizableSnapshotViewFromRect).