检测贝塞尔path内的水龙头

我有一个UIView作为子视图添加到我的视图控制器。 在这个观点上,我画了一条更加缓慢的道路。 我的drawRect实现如下

- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); UIBezierPath *bpath = [UIBezierPath bezierPath]; [bpath moveToPoint:CGPointMake(50, 50)]; [bpath addLineToPoint:CGPointMake(100, 50)]; [bpath addLineToPoint:CGPointMake(100, 100)]; [bpath addLineToPoint:CGPointMake(50, 100)]; [bpath closePath]; CGContextAddPath(context, bpath.CGPath); CGContextSetStrokeColorWithColor(context,[UIColor blackColor].CGColor); CGContextSetLineWidth(context, 2.5); CGContextStrokePath(context); UIColor *fillColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.5 alpha:0.7]; [fillColor setFill]; [bpath fill]; } 

我想检测这个贝塞尔path内部的点击,而不是UIView内部和path外部的点。 例如,在这种情况下,如果我的触摸坐标是(10,10),则不应该检测到。 我知道关于CGContextPathContainsPoint,但是当触摸在path中时,它不起作用。 有没有办法检测贝塞尔path内的触摸事件?

有一个函数CGPathContainsPoint()它可能对你有用。

另外要小心,如果你从superview得到的手势点,坐标可能不正确与您的testing。 你有一个方法convertPoint从或到特定的视图的坐标系统:

 - (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view - (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view 

试试UIBezierPath的方法 :

 func contains(_ point: CGPoint) -> Bool 

返回一个布尔值,指示接收方包含的区域是否包含指定的点。

迅速检测贝塞尔path内的水龙头: –

在最新的swift中很简单,按照这些步骤,你将得到你的UIBezierPath触摸事件。

步骤1: – 初始化点击事件查看您的UIBeizerPath添加。

///Catch layer by tap detection let tapRecognizer:UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(YourClass.tapDetected(_:))) viewSlices.addGestureRecognizer(tapRecognizer)

第2步: – 做“tapDetected”方法

  //MARK:- Hit TAP public func tapDetected(tapRecognizer:UITapGestureRecognizer){ let tapLocation:CGPoint = tapRecognizer.locationInView(viewSlices) self.hitTest(CGPointMake(tapLocation.x, tapLocation.y)) } 

第3步: – 做“hitTest”最后的方法

  public func hitTest(tapLocation:CGPoint){ let path:UIBezierPath = yourPath if path.containsPoint(tapLocation){ //tap detected do what ever you want ..;) }else{ //ooops you taped on other position in view } } 

更新:Swift 4

步骤1: – 初始化点击事件查看您的UIBeizerPath添加。

 ///Catch layer by tap detection let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourClass.tapDetected(tapRecognizer:))) viewSlices.addGestureRecognizer(tapRecognizer) 

第2步: – 做“tapDetected”方法

 public func tapDetected(tapRecognizer:UITapGestureRecognizer){ let tapLocation:CGPoint = tapRecognizer.location(in: viewSlices) self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y)) } 

第3步: – 做“hitTest”最后的方法

 private func hitTest(tapLocation:CGPoint){ let path:UIBezierPath = yourPath if path.contains(tapLocation){ //tap detected do what ever you want ..;) }else{ //ooops you taped on other position in view } } 

Swift 3.1中的解决scheme(从这里移植Apple推荐的解决scheme)

 func containsPoint(_ point: CGPoint, path: UIBezierPath, inFillArea: Bool) -> Bool { UIGraphicsBeginImageContext(self.size) let context: CGContext? = UIGraphicsGetCurrentContext() let pathToTest = path.cgPath var isHit = false var mode: CGPathDrawingMode = CGPathDrawingMode.stroke if inFillArea { // check if UIBezierPath uses EO fill if path.usesEvenOddFillRule { mode = CGPathDrawingMode.eoFill } else { mode = CGPathDrawingMode.fill } } // else mode == stroke context?.saveGState() context?.addPath(pathToTest) isHit = (context?.pathContains(point, mode: mode))! context?.restoreGState() return isHit }