如何拍摄未呈现的 UIView 的快照?
Posted
技术标签:
【中文标题】如何拍摄未呈现的 UIView 的快照?【英文标题】:How can I take a snapshot of a UIView that isn't rendered? 【发布时间】:2014-12-10 21:19:51 【问题描述】:我用这种方法拍快照:
UIView *snapshotView = [someView snapshotAfterScreenUpdates:NO];
这给了我一个可以玩的 UIView。
但是,我需要它的 UIImage 而不是 UIView。
这是我用来将 UIView 转换为 UIImage 的方法:
- (UIImage *)snapshotOfView:(UIView *)view
UIImage *snapshot;
UIGraphicsBeginImageContext(view.frame.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
不行,因为snapshotView没有渲染,所以snapshot是一个空白的UIImage。
显而易见的做法是直接对视图进行快照,而不是以 UIView 的形式进行快照,然后进行转换。
明显方法的问题是我使用的 WKWebView 有一个巨大的错误,不允许您截取屏幕截图。这是真的,我什至报告了这个错误,他们说他们正在努力修复它。
那么,如何在不渲染的情况下拍摄 snapshotView 的快照(UIImage)?
【问题讨论】:
@HussainShabbir - 不是骗子,不同的问题,不同的答案。另一个答案可能已经完成了这项工作,但这个答案与苹果当前的 api 是正确的。我知道它的效率要高得多(尽管我还没有测试过这种说法) 【参考方案1】:drawViewHierarchyInRect
将为您工作。您可以直接在 WKWebView 上使用它。
this Apple Technical Q&A 上有一些有用的细节。我还谈到了here 以回答一个略有不同的问题。
我在 UIView 上的一个类别中使用它:
@implementation UIView (ImageSnapshot)
- (UIImage*)imageSnapshot
UIGraphicsBeginImageContextWithOptions(self.bounds.size,
YES, self.contentScaleFactor);
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
@end
我不知道你所说的“显而易见的方法”是什么意思 - 但我已经在 WKWebView 上对此进行了测试,并且它有效。
【讨论】:
你先生,太棒了! 你好@foundry,我很好奇你是否仍然认为这是一个适用于 ios 9.2 和 Xcode 7.2 (7C68) 的有效解决方案?我得到一张白色的图像。 @chinjazz:我刚刚尝试了 Xcode 7.2 (7C68) 与 ios9.2 和 ios8.4 的模拟器版本(用于比较).. 都可以正常工作 感谢您的确认!我发现在模拟器中,屏幕图像将第一次为 WKWebView 呈现,但不会在下一次加载时呈现(它是白色图像).. 可能是我的错误,但我会在设备上检查它一致性。 我发现使用 WKWebView 在 webView sucCubus Navigation 之后添加延迟效果更好......【参考方案2】:由于接受者的回答对我不起作用(UIGraphicsGetImageFromCurrentImageContext()
一直返回nil
),我为 iOS10+ 找到了different solution:
let renderer = UIGraphicsImageRenderer(size: view.bounds.size)
let image = renderer.image _ in view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
附:您可能需要在渲染之前调用updateConstraintsIfNeeded()
和layoutIfNeeded()
【讨论】:
以上是关于如何拍摄未呈现的 UIView 的快照?的主要内容,如果未能解决你的问题,请参考以下文章