4

I have some UIView subclasses where I draw UIBezierPaths in drawRect. In the viewController that adds these views, I need to do a hit test to see if a tap happened inside the bezier path. I tried creating a UIBezierPath variable in the view subclass, then testing against that. But of course, the offset was completely wrong - I would get hits in the top corner of the screen, rather than over the shape.

Can anyone suggest the best way to do this? Does this make sense, or should I add some code?

Thanks, James

James White
  • 774
  • 1
  • 6
  • 18

1 Answers1

2

This is a custom triangle view I have. Its much simpler than a bezier path but I believe it should work about the same. I also have a category that hittests based on alpha level on a pixel-per-pixel basis that I use for UIImages with alpha layers. (Its in this post Retrieving a pixel alpha value for a UIImage)

- (void)drawRect:(CGRect)rect
{    
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextMoveToPoint(context, 0.0, 0.0);
    CGContextAddLineToPoint(context, rect.size.width, 0.0);
    CGContextAddLineToPoint(context, 0.0, rect.size.height);
    CGContextClosePath(context);

    CGContextSetFillColorWithColor(context, triangleColor.CGColor);
    CGContextFillPath(context);

    CGContextSaveGState(context);

    [self.layer setShouldRasterize:YES];
    [self.layer setRasterizationScale:[UIScreen mainScreen].scale];

}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    CGMutablePathRef trianglePath = CGPathCreateMutable();
    CGPathMoveToPoint(trianglePath, NULL, 0.0, 0.0);
    CGPathAddLineToPoint(trianglePath, NULL, self.frame.size.width, 0.0);
    CGPathAddLineToPoint(trianglePath, NULL, 0.0, self.frame.size.height);
    CGPathCloseSubpath(trianglePath);


    if (CGPathContainsPoint(trianglePath, nil, point, YES)) {
        CGPathRelease(trianglePath);
        return self;
    } else {
        CGPathRelease(trianglePath);
        return nil;
    }
}
Community
  • 1
  • 1
Ryan Poolos
  • 18,421
  • 4
  • 65
  • 98
  • Thanks for your help. Actually, I don't think I actually meant "hit testing", as I'm not familiar with using these methods (I'm quite new to ObjC). What I'm actually trying to do is just add a condition to touchesBegan, which checks to see if the touch happened inside the path I drew in the view. Is there a simple way to do this that doesn't involve dealing with the output of a hitTest? – James White Aug 18 '12 at 13:03
  • Use the exact same logic just in touchesBegan instead. All the code would be the same. – Ryan Poolos Aug 18 '12 at 14:05