如何在Swift中保存一个视图及其子视图的截图?

14

我希望捕获一个视图及其子视图。我正在使用以下代码来捕获屏幕:

let view = self.faceTrackerContainerView

UIGraphicsBeginImageContext(CGSizeMake(view.bounds.size.width, view.bounds.size.height))
UIGraphicsGetCurrentContext()!
self.view?.drawViewHierarchyInRect(view.frame, afterScreenUpdates: true)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)

这些代码捕获整个屏幕,包括在视图前面的按钮。我尝试了这些代码,但它只捕获主视图,不包括其子视图:

let view = self.faceTrackerContainerView
let scale = UIScreen.mainScreen().scale
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, scale);

view.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)

我也尝试了这里的snapshotViewAfterScreenUpdates(true),但不知道如何实现。我有一个collectionView在视图下面,一个按钮在视图上面(两者都不在视图内)。第一段代码捕获了包括按钮、collectionView和子视图的所有内容。第二段代码捕获了没有子视图的视图。我错过了什么吗?


你想要捕获的所有子视图都在屏幕上可见吗? - BaSha
是的,它们是。我想我只需隐藏我不想要的视图并在截图后将其放回即可。 - Vinz
5个回答

17

这对我来说是有效的,

func screenShotMethod() {
    //Create the UIImage
    UIGraphicsBeginImageContext(faceTrackerContainerView.frame.size)
    faceTrackerContainerView.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    //Save it to the camera roll
    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}

参考链接


嗨。谢谢你。这也是我得到代码的地方,它正在捕捉我屏幕上的一切。不过我只想捕捉一个带有其子视图的视图。 - Vinz
尝试使用上面代码中的 self.faceTrackerContainerView 替换 view - Mohammad Zaid Pathan
我已经尝试过了,但是视图中没有renderInContext方法。 - Vinz
很好,工作0问题。 - Bruno Sosa Fast Tag

10
extension UIView {
    func asImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }
}

从UIView中生成UIImage,然后您可以使用UIImageView(image:)方法使用该图像。


4

谢谢你提供的代码。我对此还不是很熟悉,你介意告诉我哪些部分需要更改/纠正吗? - Vinz
@Vinz:我猜提到的方法将返回一个包含渲染捕获视图的UIView,而不是直接存储在PhotosAlbum中的UIImage。 - BaSha
我尝试使用它,但是无法使其工作。其中一次尝试中得到了一个空白。 - Vinz

1
这并不十分优雅,但在截屏前隐藏视图是可行的。然后你可以在截屏后将它们显示出来。
view.isHidden = true

//screenshot

view.isHidden = false

0
  1. 将所有要包含在截图中的子视图添加到一个父视图中。

  2. 像这样绘制父视图层次结构:

      let renderer = UIGraphicsImageRenderer(size: mapParentView.bounds.size)
        let image = renderer.image { ctx in
           mapParentView.drawHierarchy(in: mapParentView.bounds, afterScreenUpdates: true)
          }
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接