Снимок экрана в части UIView, замаскированной под UIBezierPath / CGPath - PullRequest
0 голосов
/ 17 мая 2018

Я создаю приложение для рисования.Я рисую, используя 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 по-прежнему полноразмерный, не маскируется подth.

Итак, вместо того, чтобы рисовать только часть, изображенную на скриншоте, я получаю изображение всего вида / экрана.

Вопрос

Как мне успешно маскироватьвид на нарисованную область, чтобы я мог сделать снимок экрана только в этой части экрана?

1 Ответ

0 голосов
/ 17 мая 2018

Я думаю, 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)
...