2011-05-27 72 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 

我只是碰到了同樣的問題,這個固定的我!