【问题标题】:Can't generate PNG file from UIView snapshot无法从 UIView 快照生成 PNG 文件
【发布时间】:2019-12-18 20:28:03
【问题描述】:

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

这是我的代码的 sn-p:

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

任何帮助表示赞赏。

【问题讨论】:

    标签: swift uiview uiimageview uiimage uikit


    【解决方案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

    【讨论】:

    猜你喜欢
    • 2013-05-26
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 2011-06-18
    • 2021-02-07
    • 2017-02-05
    • 2015-07-08
    • 2022-08-24
    相关资源
    最近更新 更多