为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Swift中拍摄全屏截图?

如何在Swift中拍摄全屏截图?

慕哥9229398 2019-12-16 11:10:22
如何在Swift中拍摄全屏截图?我找到了以下代码:func screenShotMethod() {    //Create the UIImage    UIGraphicsBeginImageContext(view.frame.size)    view.layer.renderInContext(UIGraphicsGetCurrentContext())    let image = UIGraphicsGetImageFromCurrentImageContext()    UIGraphicsEndImageContext()    //Save it to the camera roll    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)}要使所有其他元素(如导航栏)进入屏幕截图,我需要做什么?
查看完整描述

4 回答

?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

让我解释一下当前代码的功能以及如何修改它以捕获全屏屏幕,而不是仅仅把答案扔在那里。


UIGraphicsBeginImageContext(view.frame.size)

这行代码将创建一个新的图片上下文,其大小与相同view。这里要摘录的主要内容是新图像上下文的大小与相同view。除非您要捕获应用程序的低分辨率(非视网膜)版本,否则可能应该使用它UIGraphicsBeginImageContextWithOptions。然后,您可以通过0.0获得与设备主屏幕相同的比例因子。


view.layer.renderInContext(UIGraphicsGetCurrentContext())

这行代码会将视图的图层渲染到当前的图形上下文(即您刚刚创建的上下文)中。这里要view摘录的主要内容是只有(及其子视图)被绘制到图像上下文中。


let image = UIGraphicsGetImageFromCurrentImageContext()

这行代码根据绘制到图形上下文中的内容创建一个UIImage对象。


UIGraphicsEndImageContext()

这行代码结束了图像上下文。它已经清理了(您创建了上下文,也应该将其删除。


其结果是,其大小与相同的图像view,用view和它的子视图吸入到它。


如果要将所有内容绘制到图像中,则应创建与屏幕大小相同的图像,然后将屏幕上的所有内容绘制到图像中。实际上,您可能只是在谈论应用程序“键窗口”中的所有内容。由于UIWindow是的子类UIView,因此也可以将其绘制到图像上下文中。


查看完整回答
反对 回复 2019-12-16
?
杨__羊羊

TA贡献1943条经验 获得超7个赞

斯威夫特4


    /// Takes the screenshot of the screen and returns the corresponding image

    ///

    /// - Parameter shouldSave: Boolean flag asking if the image needs to be saved to user's photo library. Default set to 'true'

    /// - Returns: (Optional)image captured as a screenshot

    open func takeScreenshot(_ shouldSave: Bool = true) -> UIImage? {

        var screenshotImage :UIImage?

        let layer = UIApplication.shared.keyWindow!.layer

        let scale = UIScreen.main.scale

        UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);

        guard let context = UIGraphicsGetCurrentContext() else {return nil}

        layer.render(in:context)

        screenshotImage = UIGraphicsGetImageFromCurrentImageContext()

        UIGraphicsEndImageContext()

        if let image = screenshotImage, shouldSave {

            UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)

        }

        return screenshotImage

    }

为Swift 2更新


您提供的代码有效,但不允许您捕获屏幕快照中的NavigationBar和StatusBar。如果要截取包含的设备的屏幕截图,则NavigationBar必须使用以下代码:


func screenShotMethod() {

    let layer = UIApplication.sharedApplication().keyWindow!.layer

    let scale = UIScreen.mainScreen().scale

    UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);


    layer.renderInContext(UIGraphicsGetCurrentContext()!)

    let screenshot = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()


    UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)

}

使用此代码:


首次启动应用程序并调用此方法时,iOS设备将询问您将图像保存在相机胶卷中的权限。

该代码的结果将是.JPG图像。

将StatusBar不会出现在最终图像。


查看完整回答
反对 回复 2019-12-16
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

细节

Xcode 9.3,Swift 4.1

Xcode 10.2(10E125)和11.0(11A420a),Swift 5

在iOS上测试:9、10、11、12


import UIKit


extension UIApplication { func makeSnapshot() -> UIImage? { return keyWindow?.layer.makeSnapshot() } }


extension CALayer {

    func makeSnapshot() -> UIImage? {

        let scale = UIScreen.main.scale

        UIGraphicsBeginImageContextWithOptions(frame.size, false, scale)

        defer { UIGraphicsEndImageContext() }

        guard let context = UIGraphicsGetCurrentContext() else { return nil }

        render(in: context)

        let screenshot = UIGraphicsGetImageFromCurrentImageContext()

        return screenshot

    }

}


extension UIView {

    func makeSnapshot() -> UIImage? {

        if #available(iOS 10.0, *) {

            let renderer = UIGraphicsImageRenderer(size: frame.size)

            return renderer.image { _ in drawHierarchy(in: bounds, afterScreenUpdates: true) }

        } else {

            return layer.makeSnapshot()

        }

    }

}


extension UIImage {

    convenience init?(snapshotOf view: UIView) {

        guard let image = view.makeSnapshot(), let cgImage = image.cgImage else { return nil }

        self.init(cgImage: cgImage, scale: image.scale, orientation: image.imageOrientation)

    }

}

用法

imageView.image = UIApplication.shared.makeSnapshot()


// or

imageView.image = view.makeSnapshot()


// or

imageView.image = view.layer.makeSnapshot()


// or

imageView.image = UIImage(snapshotOf: view)

旧解决方案

Xcode 8.2.1,快速3


适用于iOS 10x的版本1

import UIKit


extension UIApplication {


    var screenShot: UIImage?  {


        if let layer = keyWindow?.layer {

            let scale = UIScreen.main.scale


            UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);

            if let context = UIGraphicsGetCurrentContext() {

                layer.render(in: context)

                let screenshot = UIGraphicsGetImageFromCurrentImageContext()

                UIGraphicsEndImageContext()

                return screenshot

            }

        }

        return nil

    }

}

适用于iOS 9x,10x的版本2

如果您尝试在iOS 9x中使用版本1代码, 则会出现错误:CGImageCreateWithImageProvider:无效的图像提供程序:NULL。


import UIKit


extension UIApplication {


    var screenShot: UIImage?  {


        if let rootViewController = keyWindow?.rootViewController {

            let scale = UIScreen.main.scale

            let bounds = rootViewController.view.bounds

            UIGraphicsBeginImageContextWithOptions(bounds.size, false, scale);

            if let _ = UIGraphicsGetCurrentContext() {

                rootViewController.view.drawHierarchy(in: bounds, afterScreenUpdates: true)

                let screenshot = UIGraphicsGetImageFromCurrentImageContext()

                UIGraphicsEndImageContext()

                return screenshot

            }

        }

        return nil

    }

}

用法

let screenShot = UIApplication.shared.screenShot!


查看完整回答
反对 回复 2019-12-16
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

迅速UIImage扩展:


extension UIImage {


    convenience init?(view: UIView?) {

        guard let view: UIView = view else { return nil }


        UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)

        guard let context: CGContext = UIGraphicsGetCurrentContext() else {

            UIGraphicsEndImageContext()

            return nil

        }


        view.layer.render(in: context)

        let contextImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()

        UIGraphicsEndImageContext()


        guard

            let image: UIImage = contextImage,

            let pngData: Data = image.pngData()

            else { return nil }


        self.init(data: pngData)

    }


}

用法:


let myImage: UIImage? = UIImage(view: myView)


查看完整回答
反对 回复 2019-12-16
  • 4 回答
  • 0 关注
  • 707 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信