无法从UIView快照生成PNG文件

时间:2019-12-18 20:28:03

标签: swift uiview uiimageview uiimage uikit

我想从 UIView快照生成一个.png文件,但它始终为nil。您能给我一个提示我的代码有什么问题吗?我正在使用Xcode 11.3和iOS 13.3运行Catalina 10.15.2。

这是我的代码段:

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
    }
}

任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

尝试以下扩展程序:

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