I'm seeing an issue using [UIView drawViewHierarchyInRect:afterScreenUpdates:] to take an app "screenshot". Specifically, I'm seeing that a PDF rendered using QLPreviewController doesn't render in the screenshot when the code is run on a device.
I'm using this UIView API in conjunction with UIGraphicsBeginImageContextWithOptions and UIGraphicsEndImageContext - the simplified code is as follows:
UIWindow *appWindow = [[[UIApplication sharedApplication] delegate] window];
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 1.0);
CGContextRef graphicsContext = UIGraphicsGetCurrentContext();
BOOL result = [appWindow drawViewHierarchyInRect:screenBounds afterScreenUpdates:NO];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
and I'm setting up my QLPreviewController as follows:
- (void)pdfButtonTapped:(nonnull UIButton *)button {
QLPreviewController *nextViewController = [QLPreviewController new];
nextViewController.dataSource = self;
[self presentViewController:nextViewController animated:YES completion:nil];
}
#pragma mark - QLPreviewControllerDataSource
- (NSInteger)numberOfPreviewItemsInPreviewController:(nonnull QLPreviewController *)controller {
return 1;
}
- (nonnull id<QLPreviewItem>)previewController:(nonnull QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
return [NSBundle.mainBundle URLForResource:@"menu_web_november" withExtension:@"pdf"];
}
I'm running this code on both device and simulator:
Device: iPad (6th generation), iOS 15.2 [Screen 1024x768] Simulator: iPad (9th generation), iOS 15.2, Xcode 13.2.1 (13C100) [Screen 1080x810]
The results I'm seeing differ between simulator and device.
On device, I see that only the navigation bar is rendered into the final image:
On simulator, I see that the full view (including the PDF) is rendered into the final image:
On both device and simulator, the result returned from the [UIView drawViewHierarchyInRect:afterScreenUpdates:] call is YES.
I'm capturing these screenshots by setting a breakpoint in the code after UIGraphicsEndImageContext(), choosing the image variable in the debug inspector and pressing the "eye" button but note that these are the results I see when running the code in release too.
I have a couple of questions about these results:
- Is it expected that
QLPreviewControllercontents (for PDF at least) don't render in the snaphot image on device - Is it expected that
QLPreviewControllercontents (for PDF at least) do render in the snaphot image on simulator - If this behaviour is expected, is there a way of telling which UIView subclasses are "compatible" with the
[UIView drawViewHierarchyInRect:afterScreenUpdates:]API and whichUIViewsubclasses won't render their contents in a snapshot?
Thanks for your help in advance,
Ceri