У меня есть следующая функция для рисования линии между двумя точками:
override func draw(from fromPoint: CGPoint, to toPoint: CGPoint) {
let path = UIBezierPath()
path.move(to: fromPoint)
path.addLine(to: toPoint)
path.close()
layer.path = path.cgPath
layer.strokeColor = pencil.color.cgColor
layer.lineWidth = pencil.strokeSize
}
, которая вызывается в touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
Это dr aws линия и работает нормально, линия dr aws сам на правильной позиции экрана.
Затем у меня есть еще одна функция, где пользователь может стереть предыдущие рисунки, и я пытаюсь получить, если позиция касания содержится в любом из нарисованных путей:
private func findLayer(in touch: UITouch) -> CAShapeLayer? {
let point = touch.location(in: view)
// all the drawn paths are contained in CAShapeLayers
// Circles and rectangle layers have a corresponding frame that contains the UIBezierPath.
if let hitLayer = view?.layer.hitTest(point) as? CAShapeLayer,
hitLayer.path?.contains(point) == true || hitLayer.frame.contains(point) {
return hitLayer
}
guard let sublayers = view?.layer.sublayers else { return nil }
// this extra check is for layers that dont have a frame (Lines, Angle and free drawing)
for layer in sublayers {
if let shapeLayer = layer as? CAShapeLayer,
shapeLayer.path?.contains(point) == true || shapeLayer.frame.contains(point) {
return shapeLayer
}
}
return nil
}
проблема в том, что когда пользователь dr aws строка, функция findLayer никогда не возвращает слой с линией, но он отлично работает, когда пользователь dr aws круг или прямоугольник.
Я не хочу давать чертежам линии рамку, потому что тогда поле попадания может быть слишком большим, и пользователь может удалить рисунок, даже если касание не находится рядом с реальным путем.
Как можно определить, является ли точка касания частью CAShapeLayer.path?