微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

UIBelzierpath-path.containsuserTouchPoint仅可以检测userTouchPoint.y是否正好在路径Y位置

如何解决UIBelzierpath-path.containsuserTouchPoint仅可以检测userTouchPoint.y是否正好在路径Y位置

enter image description here

我有一条类似的路径(红色中间线),是从

创建的
   func drawALine(point1:CGPoint,point2:CGPoint)->CAShapeLayer{
        let path = UIBezierPath()
        path.move(to: point1)
        path.addLine(to: point2)
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.linewidth = 10
        self.layer.addSublayer(shapeLayer)
        return shapeLayer
    }

因为我有多条线,所以我必须检测我正在用哪条线

for each in RulerModelArray{
            if (!(each.midpath.path?.contains(touchPoint))!) {
                print("not contain")
            } else {
                print("contained",each.ID)
            }
        }

问题是如果我的point1 / point2 y是450,而我的touchPoint.y是450.00001,那么就不会检测到它。只有1%的人无法选择最合适的位置。

经过测试:

let testPoint:CGPoint = CGPoint(x: touchPoint.x,y: touchPoint.y + 0.0001 )
        for each in RulerModelArray{
            if (!(each.midpath.contains(testPoint))) {
                print("not contain")
            } else {
                print("contained",each.ID)
            }
        }
///always return not contain

我是否可以检测到shapeLayer.linewidth = 10中的路径?

解决方法

这是更通用的方式

适用于任何类型的直线

通过计算触摸点到目标线的距离

extension CGPoint{
    
    // tolerance,should by the lineWidth of a UIBezierPath

    func contained(byStraightLine start: CGPoint,to end: CGPoint,tolerance width: CGFloat) -> Bool{

        return distance(fromLine: start,to: end) <= width * 0.5
    }
    
    
    
    func distance(fromLine start: CGPoint,to end: CGPoint) -> CGFloat{
        
        let a = end.y - start.y
        let b = start.x - end.x
        
        let c = (start.y - end.y) * start.x + ( end.x - start.x ) * start.y
        return abs(a * x + b * y + c)/sqrt(a*a + b*b)
    }
    
}
,

您可以使用此

检查CGPoint是否在UIBezierPath的范围内

适用于水平线,因为水平线的高度为0

extension UIBezierPath{
    
    func hasForHorizontalLine(pt point: CGPoint) -> Bool{
        
        let bezierRect = bounds
        let origin = bezierRect.origin
        let size = bezierRect.size

        if origin.x <= point.x,origin.x + size.width >= point.x,origin.y - lineWidth * 0.5 <= point.y,origin.y + lineWidth * 0.5 >= point.y{
            return true
        }
        else{
            return false
        }
    }
    
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。