检测触摸UIBezierPath笔划,而不是填充

时间:2011-05-27 00:49:02

标签: iphone objective-c cocoa-touch

  

可能重复:
  How can I check if a user tapped near a CGPath?

我正在从这里关注Apple的指南

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

尝试仅在我的UIBezierPath的描边部分检测触摸事件。如果我使用UIBezierPath方法containsPoint,它工作正常,但它检测到笔划和UIBezierPath的填充部分上的触摸事件,我希望它只发生在描边部分。

按照Apple的指南(在链接的清单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];
}

然后我尝试在touchesMoved中调用containsPoint函数,如下所示:

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

2 个答案:

答案 0 :(得分:4)

如果您当前没有绘图(如touchesMoved方法中),则没有当前上下文,因此UIGraphicsGetCurrentContext()将返回NULL。

由于您对上下文所做的只是使用其当前路径,因此您也可以使用CGPathContainsPoint代替CGContextPathContainsPoint

答案 1 :(得分:1)

Apple的示例假设您在图形上下文中工作。你不是,所以你可以在方法中添加两行:

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

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

我遇到了同样的问题,这为我解决了这个问题!