您能否将当前未显示的uiview转换为uiimage

时间:2019-02-14 13:00:44

标签: ios swift uiview uiimage

我发现了许多将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)
}

2 个答案:

答案 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通过在验证用于快照测试的视图时预先强制布置视图来实现此目的。