无法从 UIView 快照生成 PNG 文件

Can't generate PNG file from UIView snapshot

我想从 UIView 快照 生成一个 .png 文件,但它总是 nil。你能提示我我的代码有什么问题吗?我是 运行 Catalina 10.15.2,Xcode 11.3 和 iOS 13.3。

这是我的代码片段:

extension UIView {

    fileprivate func snapShot(view: UIView) -> UIView {

        let snapshot = view.snapshotView(afterScreenUpdates: false)
        self.addSubview(snapshot!)
        return snapshot!
    }
}

class ViewController: UIViewController {

    var image: UIImage?
    var imageView: UIImageView?

    @IBAction func take(_ sender: UIButton) {

        let oneThird = CGRect(x: 0,
                              y: 0,
                          width: view.frame.size.width / 3,
                         height: view.frame.size.height / 3)

        let snap = view.snapShot(view: self.view)
        snap.frame = oneThird

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

            let png = snap.largeContentImage?.pngData()

            if let pngData = png {
                self.image = UIImage(data: pngData)
            }
            self.imageView = UIImageView(image: self.image)
        }
        print(self.view.subviews.indices)           // 0..<5

        print(imageView?.image as Any)              // NIL
    }
}

感谢任何帮助。

尝试以下扩展:

extension UIView {
    func getImageFromCurrentContext(bounds: CGRect? = nil) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(bounds?.size ?? self.bounds.size, false, 0.0)
        self.drawHierarchy(in: bounds ?? self.bounds, afterScreenUpdates: true)

        guard let currentImage = UIGraphicsGetImageFromCurrentImageContext() else {
            return nil
        }

        UIGraphicsEndImageContext()

        return currentImage
    }
}

如果您想要 1/3 的视图或不提供边界以获取整个视图的图像,请传递边界。

使用示例代码测试:

import UIKit

class ViewController: UIViewController {

    @IBOutlet private(set) var testView: UIView!
    @IBOutlet private(set) var testImageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            self.testImageView.image = self.testView.getImageFromCurrentContext()
        }
    }
}

我在故事板上制作了 UIView,里面有一个示例标签,并更改了背景颜色,以验证它实际上是在创建图像。然后在那下面加了一个UIImageView。将 UIView 连接到 testView,将 UIImageView 连接到 testImageView