Как центрировать путь CAShapeLayer в слое формы - PullRequest
0 голосов
/ 27 января 2020

Я создал DrawView, где можно рисовать. Я создал экземпляр UIBezierPath для рисования.

// This function is called when the user has finished drawing.
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    let shapeLayer = CAShapeLayer()

        //The CAShapeLayer has the same path of the drawing (currentPath is the instance of UIBezierPath).
        shapeLayer.path = currentPath?.cgPath
        shapeLayer.strokeColor = UIColor.black.cgColor
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineWidth = 10.0

        //Here I set the shapeLayer on the drawingView (the blue one that you can see in the image)
        drawingView.layer.addSublayer(shapeLayer)
        shapeLayer.position = CGPoint(x: drawingView.layer.bounds.midX, y: drawingView.layer.bounds.midY)
        shapeLayer.backgroundColor = UIColor.blue.cgColor
        shapeLayer.frame = drawingView.layer.bounds
}

Проблема в том, что путь (например, номер 3 на изображении) не центрирован на его shapeLayer.

shapeLayer.path?.boundingBoxOfPath = (289.5, 349.5, 525.0, 129.0)

shapeLayer.frame = (0.0, 0.0, 200.0, 200.0)

shapeLayer.position = (100.0, 100.0)

drawingView.frame = (0.0, 912.0, 200.0, 200.0)

enter image description here

Есть подсказка? спасибо

1 Ответ

1 голос
/ 28 января 2020

Забудьте о чертеже и просто подумайте, как центрировать путь в слое фигуры известного размера. Вот преднамеренная ошибка:

    let path = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 50, height: 50))
    let lay = CAShapeLayer()
    lay.frame = CGRect(x: 40, y: 40, width: 200, height: 200)
    lay.backgroundColor = UIColor.red.cgColor
    lay.path = path.cgPath
    self.view.layer.addSublayer(lay)

Мы получаем это:

enter image description here

Залитый круг не центрирован в слое красной формы , Хорошо, мы знаем почему, потому что мы знаем безье, который создал закрашенный круг. Но допустим, мы не знаем это. Мы все еще можем центрировать фигуру в слое фигуры, например:

    let path = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 50, height: 50))
    let lay = CAShapeLayer()
    lay.frame = CGRect(x: 40, y: 40, width: 200, height: 200)
    lay.backgroundColor = UIColor.red.cgColor

    let cgpath = path.cgPath
    let box = cgpath.boundingBoxOfPath
    let xtarget = (lay.bounds.width - box.width)/2
    let ytarget = (lay.bounds.height - box.height)/2
    let xoffset = xtarget - box.minX
    let yoffset = ytarget - box.minY
    var transform = CGAffineTransform(translationX: xoffset, y: yoffset)
    let cgpath2 = cgpath.copy(using: &transform)
    lay.path = cgpath2

    self.view.layer.addSublayer(lay)

Результат:

enter image description here

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

...