ios - 如何使用贝塞尔曲线路径在 swift 4 中用箭头创建虚线?

标签 ios swift uibezierpath

我想在用户触摸点上创建一个带有虚线的箭头。

这是我的代码。但是我没有任何解决方案。

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)
    }    
}

enter image description here

我已附上要求的屏幕截图。

最佳答案

请为您的解决方案尝试以下代码,

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)
    }
}

输出:

output

测试数据:

let startTouchPoint = CGPoint(x: 200, y: 200)
let secondTouchPoint = CGPoint(x: 50, y: 50)

关于ios - 如何使用贝塞尔曲线路径在 swift 4 中用箭头创建虚线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53946432/

相关文章:

ios - 如何从 CGPath 获取封闭的子路径

ios - Swift 3.0 绘制具有相同起始角度和结束角度的圆,结果成直线

objective-c - 告诉自定义委托(delegate)何时调用方法

ios - 来自应用程序委托(delegate)的停止动画事件指示器

ios - 无法生成位码包,因为

ios - Swift 4 将歌曲上传到 Apple Music Library

ios - 带阴影的线圆

ios - 无法理解这个返回语句

ios - 当我的应用程序在后台运行时,是否可以获取用户正在使用的当前应用程序?

linux - Swift3 Linux vc Mac DispatchQueue