屏蔽到UIBezierPath / CGPath的UIView的部分屏幕截图

时间:2018-05-17 17:12:11

标签: swift mask uibezierpath cgpath

我正在构建一个绘图应用程序。我正在使用CGMutablePath绘图 我希望用户能够选择一部分绘制路径,然后移动该部分,如下所示:

selection demo

我想,一个可能的解决方案是将视图遮盖到绘制区域,然后在该视图中截取屏幕截图 在这里,您可以看到我想要截取屏幕的区域:

selecting an area

要截取屏幕截图,我会绘制last路径,即屏幕截图所在的区域:

let shapeLayer = CAShapeLayer()
shapeLayer.path = last.closedPath // returns CGPath.closeSubpath()
shapeLayer.lineWidth = 10

然后我创建一个overlayView,这是我正在截取屏幕截图的视图。

let overlayView = UIView(frame: view.bounds)
overlayView.backgroundColor = .black
overlayView.alpha = 0.4
view.addSubview(overlayView)
view.bringSubview(toFront: overlayView)

然后我将视图掩盖到路径:

overlayView.mask(withPath: UIBezierPath(cgPath: last.closedPath!))

.mask(withPath:)方法来自此处:

extension UIView {
    func mask(withPath path: UIBezierPath) {
        let path = path
        let maskLayer = CAShapeLayer()
        maskLayer.path = path.cgPath

        self.layer.mask = maskLayer
    }
}

然后,我在overlayView中截取屏幕截图:

let image: UIImage = {
    UIGraphicsBeginImageContextWithOptions(overlayView.bounds.size, false, 0)
    defer { UIGraphicsEndImageContext() }
    drawView.drawHierarchy(in: overlayView.bounds, afterScreenUpdates: true)
    return UIGraphicsGetImageFromCurrentImageContext()!
}()

UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)

会发生什么,overlayView是否具有屏幕的完整尺寸,并且还以完整尺寸绘制屏幕截图。
在调试视图层次结构时,我还可以看到overlayView仍然是全尺寸的,而不是屏蔽到路径。

因此,我得到的是整个视图/屏幕的图像,而不仅仅是截取屏幕截图。

问题

如何成功地将视图屏蔽到绘制区域,以便我只能在屏幕的该部分截取屏幕截图?

1 个答案:

答案 0 :(得分:0)

我认为overlayView.frame等于self.view.frame,这就是图片全屏播放的原因。

您的问题的解决方案可以解决如下(虽然我可能已经错误理解):

let shapeLayer = CAShapeLayer()
shapeLayer.path = last.closedPath // returns CGPath.closeSubpath()
shapeLayer.lineWidth = 10
let rect = shapeLayer.path.boundingBoxOfPath

let overlayView = UIView(frame: rect)