Ios 检测贝塞尔路径内的抽头

Ios 检测贝塞尔路径内的抽头,ios,objective-c,core-graphics,uibezierpath,Ios,Objective C,Core Graphics,Uibezierpath,我有一个UIView,它作为子视图添加到我的视图控制器中。我在那个视图上画了一条贝塞尔路径。下面是我的drawRect实现 - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); UIBezierPath *bpath = [UIBezierPath bezierPath]; [bpath moveToPoint:CGPointMake(50, 50)];

我有一个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];
}

我想在这个贝塞尔路径内检测点击,但不是在UIView内和路径外的点。例如,在这种情况下,如果我的触摸坐标为(10,10),则不应检测到它。我知道CGContextPathContainsPoint,但当触摸在路径内时,它没有帮助。有没有办法检测bezier path内部的触摸事件?

有一个函数
CGPathContainsPoint()
在您的情况下可能很有用

另外,如果您从superview获取手势点,也要小心,测试中的坐标可能不正确。有一种方法可以将点从特定视图的坐标系转换或转换到特定视图的坐标系:

- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view
请尝试UIBezierPath的:

返回一个布尔值,该值指示 接收器包含指定的点


在swift:-

最新的swift很简单,按照以下步骤操作,您将获得UIBezierPath触摸事件

步骤1:-在添加UIBeizerPath的视图上初始化点击事件。

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


}
  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
        }
    }
///Catch layer by tap detection
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourClass.tapDetected(tapRecognizer:)))
viewSlices.addGestureRecognizer(tapRecognizer)
public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: viewSlices)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))
}
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
    }
}
///逐点捕获层检测
让tapRecognizer:UITapGestureRecognizer=UITapGestureRecognizer.init(目标:self,操作:#选择器(YourClass.tapDetected(:))
viewSlices.addGestureRecognizer(tapRecognizer)

第2步:-采用“检测到”方法

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


}
  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
        }
    }
///Catch layer by tap detection
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourClass.tapDetected(tapRecognizer:)))
viewSlices.addGestureRecognizer(tapRecognizer)
public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: viewSlices)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))
}
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
    }
}
步骤3:-制定“hitTest”最终方法

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


}
  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
        }
    }
///Catch layer by tap detection
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourClass.tapDetected(tapRecognizer:)))
viewSlices.addGestureRecognizer(tapRecognizer)
public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: viewSlices)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))
}
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 4

步骤1:-在添加UIBeizerPath的视图上初始化点击事件。

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


}
  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
        }
    }
///Catch layer by tap detection
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourClass.tapDetected(tapRecognizer:)))
viewSlices.addGestureRecognizer(tapRecognizer)
public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: viewSlices)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))
}
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
    }
}
第2步:-采用“检测到”方法

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


}
  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
        }
    }
///Catch layer by tap detection
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourClass.tapDetected(tapRecognizer:)))
viewSlices.addGestureRecognizer(tapRecognizer)
public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: viewSlices)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))
}
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
    }
}
步骤3:-制定“hitTest”最终方法

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


}
  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
        }
    }
///Catch layer by tap detection
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourClass.tapDetected(tapRecognizer:)))
viewSlices.addGestureRecognizer(tapRecognizer)
public func tapDetected(tapRecognizer:UITapGestureRecognizer){
    let tapLocation:CGPoint = tapRecognizer.location(in: viewSlices)
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y))
}
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中的解决方案(移植到苹果公司推荐的解决方案上)


也许您需要添加
CGPathCloseSubpath
。我已经更新了我的答案。请检查。“检测此贝塞尔路径内的点击,而不是在UIView内”此贝塞尔路径在UIView内绘制,那么点击怎么可能在其内而不是在UIView内呢?@matt:编辑了question@blancos-谢谢,只是要确保我们都在同一页上!:)CGPathCloseSubpath()不接受bpath作为参数。我已经尝试了bpath.CGPathalso@AbhimanyuRathore-谢谢你的解释,迪奥戈,谢谢你的Swift 4更新!我得到了这个功能的大部分工作,但我有准确性的问题。。我已经在这里详细描述了这个问题:我想知道你们中的一个或两个是否可以评论。。。我们将非常感谢您提供的任何解决问题的提示。@DiogoSouza(也为您添加标签,以防万一..提前感谢您)亲爱的@Matvey我试图在这里解释您的问题。谢谢。@Matvey需要在我们的视图中将UIGraphicsGetCurrentContext替换为CAShapeLayer,我们正在使用它在UIViewcontroller内部进行tapDetection。@Matvey StyleKit.drawA5函数需要修改,在这里我们需要将UIGraphicsGetCurrentContext替换为CAShapeLayer,以便UIBezierPath用于aquracy