我发现了许多将UIView转换为UIImage的示例,并且它们在视图被布局好后就可以很好地工作。即使在我的视图控制器中有很多行,其中一些行仍然显示在屏幕上,我可以做转换。不幸的是,对于表中距离视图太远(因此尚未“绘制”)的某些视图,进行转换会生成空白的UIImage。
我尝试调用setNeedsDisplay和layoutIfNeeded,但是它们不起作用。我什至尝试过自动滚动表,但也许我没有采取某种方式(使用线程)来确保在转换发生之前先进行滚动,从而允许视图更新。我怀疑无法完成此操作,因为我发现了各种各样的问题,没有人找到解决方案。另外,是否可以只在UIImage中重绘整个视图,而不需要UIView?
从Paul Hudson的网站
使用未在屏幕上显示的任何UIView(例如,UITableview中的一行位于屏幕底部下方。
let renderer = UIGraphicsImageRenderer(size: view.bounds.size)
let image = renderer.image { ctx in
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
}
答案 0 :(得分:1)
您也可以使用UIGraphicsImageRenderer
完成此操作。
extension UIView {
func image() -> UIImage {
let imageRenderer = UIGraphicsImageRenderer(bounds: bounds)
if let format = imageRenderer.format as? UIGraphicsImageRendererFormat {
format.opaque = true
}
let image = imageRenderer.image { context in
return layer.render(in: context.cgContext)
}
return image
}
}
答案 1 :(得分:0)
您不必在窗口/屏幕上查看视图就能将其渲染为图像。我已经在PixelTest中做到了这一点:
extension UIView {
/// Creates an image from the view's contents, using its layer.
///
/// - Returns: An image, or nil if an image couldn't be created.
func image() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.saveGState()
layer.render(in: context)
context.restoreGState()
guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return nil }
UIGraphicsEndImageContext()
return image
}
}
如果视图要在屏幕上呈现,它将把视图的图层呈现为当前图像。也就是说,如果尚未布局视图,则外观将不会达到您的期望。 PixelTest通过在验证用于快照测试的视图时预先强制布置视图来实现此目的。