如何在后台线程上截取 UIView 的屏幕截图?
Posted
技术标签:
【中文标题】如何在后台线程上截取 UIView 的屏幕截图?【英文标题】:How to take a screenshot of UIView on a background thread? 【发布时间】:2018-10-02 12:37:54 【问题描述】:我正在开发的应用程序几乎每个屏幕上都有谷歌地图。为了节省内存,我到处重复使用相同的谷歌地图视图。问题是,当您弹出视图控制器时,您可以看到地图所在的空白区域。为了解决这个问题,我在删除地图之前对其进行截图并添加为背景。但是还有另一个问题,在 iPhoneX 上截屏大约需要 0.3 秒(我想在旧手机上更糟)。有没有办法在后台线程上截取 UIView 的截图?
【问题讨论】:
***.com/questions/42778797/… 。参考我的答案 您对我的问题投了反对票,但您的回答与此无关。再读一遍。我需要在背景线程上截屏。您的答案仅适用于主线程。 嘿,我为什么要对你的问题投反对票,伙计,我来这里是为了帮助其他人,我与你的问题没有任何关系,我没有对你的问题投反对票 我不认为你可以在后台线程中捕获屏幕截图,你必须在主线程中进行***.com/questions/52605016/… 【参考方案1】:我使用 swift 尝试了所有最新的快照方法。其他方法在后台对我不起作用。但是以这种方式拍摄快照对我有用。
使用参数视图层和视图边界创建扩展。
extension UIView
func asImageBackground(viewLayer: CALayer, viewBounds: CGRect) -> UIImage
if #available(ios 10.0, *)
let renderer = UIGraphicsImageRenderer(bounds: viewBounds)
return renderer.image rendererContext in
viewLayer.render(in: rendererContext.cgContext)
else
UIGraphicsBeginImageContext(viewBounds.size)
viewLayer.render(in:UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return UIImage(cgImage: image!.cgImage!)
用法
DispatchQueue.main.async
let layer = self.selectedView.layer
let bounds = self.selectedView.bounds
DispatchQueue.global(qos: .background).async
let image = self.selectedView.asImageBackground(viewLayer: layer, viewBounds: bounds)
我们需要在主线程中计算层和边界,然后其他操作将在后台线程中进行。它将提供流畅的用户体验,不会在 UI 中出现任何延迟或中断。
【讨论】:
【参考方案2】:其实是可以的!但首先在 UIThread 上,您需要获取一些信息,如下所示:
CALayer* layer = view.layer;
CGRect frame = view.frame;
,然后改成 backgroundthead 使用下面的代码来获取图像:
UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
[layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
【讨论】:
我不断收到此消息“在从主线程访问引擎后,此应用程序正在从后台线程修改自动布局引擎。这可能导致引擎损坏和奇怪的崩溃。”。但一切似乎都奏效了。 但实际上这种截屏方法足够快,我什至不需要后台线程。【参考方案3】:来自 UIKit documentation
除非另有说明,否则只能从应用的主线程或主调度队列中使用 UIKit 类。此限制特别适用于从 UIResponder 派生的类或涉及以任何方式操纵您应用的用户界面的类。
我认为没有办法在后台线程上对视图进行快照,因为您使用的是 UIKit 方法。
【讨论】:
以上是关于如何在后台线程上截取 UIView 的屏幕截图?的主要内容,如果未能解决你的问题,请参考以下文章