2011-05-27 12 views
6

Possible Duplicate:
How can I check if a user tapped near a CGPath?detectan el tacto sobre el accidente cerebrovascular UIBezierPath, no llena

estoy siguiendo la guía de Apple de aquí

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

para tratar de detectar un evento de toque solamente en la parte de mi acariciado UIBezierPath. Si utilizo el método UIBezierPath, containsPoint, funciona bien, pero detecta los eventos táctiles en el trazo y la parte de relleno de UIBezierPath, y quiero que solo ocurra en la parte trazada.

siguiente guía de Apple (en el listado 3-6 del enlace), he creado esta función:

- (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; 
} 

Cuando yo lo llamo, me sale:

error: CGContextSaveGState: inválido 0x0 contexto
error: CGContextAddPath: inválido 0x0 contexto
error: CGContextPathContainsPoint: inválido 0x0 contexto
error: CGContextRestoreGState: inválido 0x0 contexto

Aquí es función drawRect de mi vista, y mi código para crear mi camino:

- (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]; 
} 

entonces yo estoy tratando de llamar a la función containsPoint interior de touchesMoved, así:

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

¿Alguna vez encontró una solución para esto? Esta publicación es # 1 en internet para todas las preguntas relacionadas con esto, pero no hay respuesta :) – shawnwall

+1

Agrego mi voz a la de Shawnall, ¿has logrado resolver esto? Espero que pueda compartir la solución si tiene – Abolfoooud

Respuesta

4

Cuando Actualmente no está dibujando (como en el método touchesMoved), no existe un contexto actual, por lo que UIGraphicsGetCurrentContext() devolverá NULL.

Como todo lo que está haciendo con el contexto es usar su ruta actual, también podría usar CGPathContainsPoint en lugar de CGContextPathContainsPoint.

+0

Eso tiene sentido. Gracias. ¿Cómo podría llamar a CGPathContainsPoint? Llamarlo como: if (! CGPathContainsPoint ([self createPath] .CGPath, nil, c, false)) return; Produce lo mismo que UIBezierPath.containsPoint, ya que parece recoger las áreas de trazo y relleno. Llamarlo como: if (! CGPathContainsPoint ([self createPath], nil, c, false)) return; no parece funcionar en absoluto. – james

+0

Ah, tienes razón, no funcionará de esta manera. No noté el parámetro fillMode. Aparentemente necesitas un CGContext para hacer la detección de golpe en la parte de golpe. Quizás podría crear un contexto de mapa de bits pequeño para esto, usando CGBitmapContextCreate (encontrará muchas preguntas al respecto en SO). – omz

1

El ejemplo de Apple asume que está trabajando dentro de un contexto de gráficos. No eres, lo que sólo puede añadir dos líneas al método:

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

y

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

Me acabo de encontrar con el mismo problema, y ​​esto lo arreglaron para mí!

Cuestiones relacionadas