ios - 如何使用帮助贝塞尔路径在swift 4中使用箭头创建虚线?
问题描述
我想在用户接触点上创建一个带有虚线的箭头。
这是我的代码。但我没有任何解决方案。
let arrow = UIBezierPath()
arrow.addArrow(start: CGPoint(x: startTouch!.x, y: startTouch!.y), end: CGPoint(x: secondTouch!.x, y: secondTouch!.y), pointerLineLength: 20, arrowAngle: CGFloat(Double.pi / 5))
self.currentContext?.setLineCap(.round)
self.currentContext?.setLineJoin(.round)
self.currentContext?.addPath(arrow.cgPath)
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.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)
}
}
我已附上要求的屏幕截图。
解决方案
请尝试以下代码作为您的解决方案,
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let arrow = UIBezierPath()
let startTouchPoint = CGPoint(x: startTouch!.x, y: startTouch!.y) //CGPoint(x: 200, y: 200)
let secondTouchPoint = CGPoint(x: secondTouch!.x, y: secondTouch!.y) //CGPoint(x: 50, y: 50)
arrow.addArrow(start: startTouchPoint, end: secondTouchPoint, pointerLineLength: 20, arrowAngle: CGFloat(Double.pi / 5))
let arrowLayer = CAShapeLayer()
let path = CGMutablePath()
arrowLayer.strokeColor = UIColor.red.cgColor
arrowLayer.lineDashPattern = [7, 6]
arrowLayer.lineWidth = 3
path.addPath(arrow.cgPath)
path.addLines(between: [startTouchPoint, secondTouchPoint])
arrowLayer.path = path
arrowLayer.fillColor = UIColor.clear.cgColor
arrowLayer.lineJoin = CAShapeLayerLineJoin.round
arrowLayer.lineCap = CAShapeLayerLineCap.round
self.view.layer.addSublayer(arrowLayer)
}
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)
}
}
输出:
测试数据:
let startTouchPoint = CGPoint(x: 200, y: 200)
let secondTouchPoint = CGPoint(x: 50, y: 50)
推荐阅读
- java - 为什么Android Studio模拟器显示黑屏?
- spring - 禁用 Spring Cloud 安全性
- celery - 通过 send_task 让正确的工作人员执行任务
- javascript - 为什么我的四叉树没有提高性能?
- python - Django检查超级用户是否在基于类的视图中
- python - 在c#TcpClient中接收从Python发送的视频帧
- seurat - CreateSeuratObject:输入矩阵中没有单元格名称(列名)名称
- python - 如何在 Python 中使用变量名作为字符串
- python - 如何为振荡图绘制信封
- angular - VSCode:'router-outlet'不是已知元素角度10