问题
I have lines in many directions and angles, I draw them using UIBezierpath
.
I need to draw an arrow on one of the ends of the line; dynamically depending on given point.
Edit:
Edit 2: with Jake answer here is my code
let y2 = line.point2Y
let path = UIBezierPath()
path.move(to: CGPoint(x: x1, y: y1))
path.addLine(to: CGPoint(x: x2, y: y2))
path.addArrow(start: CGPoint(x: x1, y: y1), end: CGPoint(x: x2, y: y2), pointerLineLength: ...
path.close()
let shape = CAShapeLayer()
let shapeBorder = CAShapeLayer()
shapeBorder.strokeColor = UIColor.black.cgColor
shapeBorder.lineJoin = kCALineJoinRound
shapeBorder.lineCap = kCALineCapRound
shapeBorder.lineWidth = 10
shapeBorder.addSublayer(shape)
shape.path = path.cgPath
shapeBorder.path = shape.path
shape.lineJoin = kCALineJoinRound
shape.lineCap = kCALineCapRound
shape.lineWidth = shapeBorder.lineWidth-5.0
shape.strokeColor = color
But there is a shadow
回答1:
This works for me:
extension UIBezierPath {
func addArrow(start: CGPoint, end: CGPoint, pointerLineLength: CGFloat, arrowAngle: CGFloat) {
self.move(to: start)
self.addLine(to: end)
let startEndAngle = atan((end.y - start.y) / (end.x - start.x)) + ((end.x - start.x) < 0 ? CGFloat(Double.pi) : 0)
let arrowLine1 = CGPoint(x: end.x + pointerLineLength * cos(CGFloat(Double.pi) - startEndAngle + arrowAngle), y: end.y - pointerLineLength * sin(CGFloat(Double.pi) - startEndAngle + arrowAngle))
let arrowLine2 = CGPoint(x: end.x + pointerLineLength * cos(CGFloat(Double.pi) - startEndAngle - arrowAngle), y: end.y - pointerLineLength * sin(CGFloat(Double.pi) - startEndAngle - arrowAngle))
self.addLine(to: arrowLine1)
self.move(to: end)
self.addLine(to: arrowLine2)
}
}
class MyViewController : UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let arrow = UIBezierPath()
arrow.addArrow(start: CGPoint(x: 200, y: 200), end: CGPoint(x: 50, y: 50), pointerLineLength: 30, arrowAngle: CGFloat(Double.pi / 4))
let arrowLayer = CAShapeLayer()
arrowLayer.strokeColor = UIColor.black.cgColor
arrowLayer.lineWidth = 3
arrowLayer.path = arrow.cgPath
arrowLayer.fillColor = UIColor.clear.cgColor
arrowLayer.lineJoin = kCALineJoinRound
arrowLayer.lineCap = kCALineCapRound
self.view.layer.addSublayer(arrowLayer)
}
}
EDIT
Also, make sure you set your the fillColor
of your CAShapeLayer
to UIColor.clear.cgColor
. Otherwise, your layer will fill in the area between the start point of the arrow and one of the lines at the end.
来源:https://stackoverflow.com/questions/48625763/how-to-draw-a-directional-arrow-head