我有一个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];
}
我希望在此bezier路径中检测tap,但不是在UIView内部和路径外部的点。例如,在这种情况下,如果我的触摸坐标是(10,10),则不应检测到它。我知道CGContextPathContainsPoint但是当触摸在路径内时它没有帮助。有没有办法检测bezier路径内的触摸事件?
答案 0 :(得分:17)
有一个函数CGPathContainsPoint()
它可能对你的情况有用。
如果从superview获得手势点,也要小心,测试时坐标可能不正确。您有一种方法可以将Point转换为特定视图的坐标系:
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view
答案 1 :(得分:8)
答案 2 :(得分:6)
在swift中检测bezier路径内的tap: -
最新的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
}
}
答案 3 :(得分:1)
Swift 3.1中的解决方案(移植来自here的Apple推荐解决方案)
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
}