2011-05-27 73 views
6

Possible Duplicate:
How can I check if a user tapped near a CGPath?检测上UIBezierPath中风触摸,不填

我下面从这里

http://developer.apple.com/library/ios/#documentation/2DDrawing/Conceptual/DrawingPrintingiOS/BezierPaths/BezierPaths.html

苹果的指导,试图只在我的UIBezierPath的抚摸部分检测的触摸事件。如果我使用UIBezierPath方法containsPoint,它可以正常工作,但它检测笔触和UIBezierPath的填充部分上的触摸事件,并且我希望它只出现在笔触部分上。

继苹果指南(在链路的上市3-6),我创造了这个功能:

- (BOOL)containsPoint:(CGPoint)point onPath:(UIBezierPath*)path inFillArea:(BOOL)inFill 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext();  
    CGPathRef cgPath = path.CGPath;  
    BOOL isHit = NO; 

    // Determine the drawing mode to use. Default to  
    // detecting hits on the stroked portion of the path.  
    CGPathDrawingMode mode = kCGPathStroke;  
    if (inFill)   
    { 
     // Look for hits in the fill area of the path instead. 
     if (path.usesEvenOddFillRule) 
      mode = kCGPathEOFill; 
     else 
      mode = kCGPathFill; 
    } 

    // Save the graphics state so that the path can be 
    // removed later. 
    CGContextSaveGState(context); 
    CGContextAddPath(context, cgPath); 

    // Do the hit detection. 
    isHit = CGContextPathContainsPoint(context, point, mode); 
    CGContextRestoreGState(context); 
    return isHit; 
} 

当我打电话吧,我得到:

错误:CGContextSaveGState:无效的上下文为0x0
错误:CGContextAddPath:无效的情况下为0x0
错误:CGContextPathContainsPoint:无效的情况下为0x0
错误:CGContextRestoreGState:无效的情况下为0x0

这是我的观点的drawRect功能,我的代码来创建我的路径:

- (UIBezierPath *) createPath { 
    static UIBezierPath *path = nil; 
    if(!path) { 
     path = [[UIBezierPath bezierPathWithOvalInRect:CGRectMake(35, 45, 250, 250)] retain]; 
     path.lineWidth = 50.0; 
     [path closePath]; 
    }  
    return path; 
} 

/* 
// Only override drawRect: if you perform custom drawing. 
// An empty implementation adversely affects performance during animation. 
*/ 
- (void)drawRect:(CGRect)rect 
{ 
    // Drawing code 

    //draw a circle 
    UIBezierPath *aPath = [self createPath]; 

    //set stroke width 
    aPath.lineWidth = 50.0; 

    //set stroke color 
    [[UIColor blueColor] setStroke]; 

    //stroke path 
    [aPath stroke]; 

    //close path 
    [aPath closePath]; 

    //add a label at the "top" 
    UILabel *topLabel; 
    topLabel = [[UILabel alloc]initWithFrame:CGRectMake(120, -5, 80, 25)]; 
    topLabel.text = @"The Top"; 
    [self addSubview:topLabel]; 
} 

然后我试图调用containsPoint功能touchesMoved内,像这样:

if (![self containsPoint:c onPath:[self createPath] inFillArea:NO]) return; 
+1

您是否曾经为此找到过解决方案?这篇文章是互联网上排名第一的所有与此有关的问题,但没有答案:) – shawnwall 2012-01-23 18:46:58

+1

我把我的声音添加到shawnall's,你是否设法解决了这个问题?希望你可以分享这个解决方案,如果你有任何 – Abolfoooud 2012-08-28 09:56:54

回答

4

当你目前没有绘制(如在touchesMoved方法中),没有当前上下文,所以UIGraphicsGetCurrentContext()将返回NULL。

正如你在上下文中所做的一样是使用它的当前路径,你可以使用CGPathContainsPoint而不是CGContextPathContainsPoint

+0

这是有道理的。谢谢。我将如何调用CGPathContainsPoint?调用它像:if(!CGPathContainsPoint([self createPath] .CGPath,nil,c,false))return;结果与UIBezierPath.containsPoint相同,因为它似乎可以同时获取笔划和填充区域。调用它像:if(!CGPathContainsPoint([self createPath],nil,c,false))return;似乎并没有工作。 – james 2011-05-27 01:18:34

+0

啊,你是对的,它不会这样工作。我没有注意到fillMode参数。显然你需要一个CGContext来对笔画部分进行点击检测。也许你可以使用CGBitmapContextCreate为你创建一个小的位图上下文(你会发现很多关于这个的问题)。 – omz 2011-05-27 01:57:30

1

Apple的例子假设你在图形上下文中工作。你没有,那么你可以只增加两行的方法:

UIGraphicsBeginImageContext(self.frame.size); // ADD THIS... 
CGContextRef context = UIGraphicsGetCurrentContext(); // ...before this 

CGContextRestoreGState(context); // after this... 
UIGraphicsEndImageContext(); // ADD THIS 

我只是碰到了同样的问题,这个固定的我!