可以把当前没有显示的uiview转成uiimage吗
Can you convert uiview that is not currently being displayed to uiimage
我发现了很多将 UIView 转换为 UIImage 的例子,一旦视图被布局等,它们就可以完美地工作。即使在我的视图控制器中有很多行,其中一些是净的但显示在屏幕上,我可以做转换。不幸的是,对于一些在 table 中太靠后的视图(因此还没有 "drawn"),进行转换会产生一个空白的 UIImage。
我试过调用 setNeedsDisplay 和 layoutIfNeeded,但它们不起作用。我什至尝试过自动滚动 table,但也许我没有以某种方式(使用线程)确保首先发生滚动,从而允许在转换发生之前更新视图。我怀疑这无法完成,因为我发现了各种问题,并且 none 找到了解决方案。或者,我可以只在 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)
}
您不必在 window/on-screen 中拥有视图即可将其呈现为图像。我在 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 通过在验证快照测试视图时预先强制布局视图来做到这一点。
您也可以使用 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
}
}
我发现了很多将 UIView 转换为 UIImage 的例子,一旦视图被布局等,它们就可以完美地工作。即使在我的视图控制器中有很多行,其中一些是净的但显示在屏幕上,我可以做转换。不幸的是,对于一些在 table 中太靠后的视图(因此还没有 "drawn"),进行转换会产生一个空白的 UIImage。
我试过调用 setNeedsDisplay 和 layoutIfNeeded,但它们不起作用。我什至尝试过自动滚动 table,但也许我没有以某种方式(使用线程)确保首先发生滚动,从而允许在转换发生之前更新视图。我怀疑这无法完成,因为我发现了各种问题,并且 none 找到了解决方案。或者,我可以只在 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)
}
您不必在 window/on-screen 中拥有视图即可将其呈现为图像。我在 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 通过在验证快照测试视图时预先强制布局视图来做到这一点。
您也可以使用 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
}
}