Reputation: 528
I'm trying to detect wether a user clicks on a image in draw with a CGContext and a path as below (this happens in a customview class called SwbPlate:
SwbPlateImage * image;
CGFloat startAngle;
CGFloat endAngle;
CGContextRef context = UIGraphicsGetCurrentContext();
for (image in plateImages) {
endAngle = [EntGeometry pointToRadian:[image endPoint] withCenterPoint:CGPointMake(self.bounds.size.width/2 , self.bounds.size.height /2)];
startAngle = [EntGeometry pointToRadian:[image startPoint] withCenterPoint:CGPointMake(self.bounds.size.width/2 , self.bounds.size.height /2)];
imageToDraw = [image plateImg];
NSLog(@"%@", image);
CGContextSaveGState(context);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.bounds.size.width/2 , self.bounds.size.height/2);
CGPathAddArc( path,
NULL,
self.bounds.size.width/2,
self.bounds.size.height/2,
(self.bounds.size.width/2),
endAngle,
startAngle,
0);
CGPathCloseSubpath(path);
CGContextAddPath(context, path);
CGContextClip(context);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, rect, [imageToDraw CGImage]);
CGContextRestoreGState(context);
//RVE MOD
image.imageContext = context;
Then i try to see if the user has touches moved on a point within this context but this does not seem to work
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
NSArray *allTouches = [touches allObjects];
UITouch *touch = [allTouches objectAtIndex:0];
SwbDragProduct*dragProd;
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[SwbPlateView class]] &(CGRectContainsPoint([view frame], [touch locationInView:self.view])) ) {
NSLog(@" We touched in the PLATE");
for (SwbPlateImage *imgView in plateView.plateImages){
if(CGContextPathContainsPoint(imgView.imageContext, [touch locationInView:self.view],kCGPathFillStroke)){
NSLog(@" We Touched within the IMAGE");
}
}
}
Upvotes: 1
Views: 885
Reputation: 326
- (BOOL)pathContainsPoint:(NSPoint)point forMode:(CGPathDrawingMode)mode
{
CGPathRef path = [self quartzPath]; // Custom method to create a CGPath
CGContextRef cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
CGPoint cgPoint;
BOOL containsPoint = NO;
cgPoint.x = point.x;
cgPoint.y = point.y;
// Save the graphics state before doing the hit detection.
CGContextSaveGState(cgContext);
CGContextAddPath(cgContext, path);
containsPoint = CGContextPathContainsPoint(cgContext, cgPoint, mode);
CGContextRestoreGState(cgContext);
return containsPoint;
}
Upvotes: 1
Reputation: 371
What I am looking for is a tap detection on the CGContextImage I found that in order to do what I needed detecting the tap on the CGContext image was not the correct approach.
I have a list of points in memory that I know the coords of and in order to detect taps on the uiscrollview I iterated over these to see if the point i tapped is inside the bounding box of the image I had already drawn. This works for me perfectly and I am able to detect taps on the image by calculating the coords and updating the scale etc. of the scrollview to transform the coords into the correct scale also.
So in short the answer I have come to is that it is not possible to get the CGContext image to detect a tap but instead use their known positions in order to identify a hit yourself.
Thanks Damien
Upvotes: 1
Reputation: 7504
It seems to me that you have SwbPlateImage local variable where you are assigning context which is not available in the for loop when you are checking for context. You will need to have Singleton class(say SwbPlateImageSingleTon) that manages and stores SwbPlateImage's context objects. I can help you writing singleton class if you can give some more details about the classes you mentioned in the question.
From your question, it looks like, you will need to have NSMutableArray(say contextArray) of CGContextRef as a strong object in the singleton class. Rather than assigning context to image.imageContext, add context into this array.
[[SwbPlateImageSingleTon sharedInstance] contextArray] addObject:context]
Then your inner loop will look like below.
for (CGContextRef context in [[SwbPlateImageSingleTon sharedInstance] contextArray]) {
if(CGContextPathContainsPoint(context, [touch locationInView:self.view],kCGPathFillStroke)) {
NSLog(@" We Touched within the IMAGE");
}
}
Singleton class
SwbPlateImageSingleTon.h
@interface SwbPlateImageSingleTon : NSObject
@property (strong, nonatomic) NSMutableArray *contextArray;
+ (SwbPlateImageSingleTon*)sharedInstance;
@end
SwbPlateImageSingleTon.m
#import "SwbPlateImageSingleTon.h"
@implementation SwbPlateImageSingleTon
static SwbPlateImageSingleTon *sharedObject = nil;
+ (SwbPlateImageSingleTon*)sharedInstance
{
@synchronized(self) {
if (!sharedObject) {
sharedObject = [[SwbPlateImageSingleTon alloc] init];
}
return sharedObject;
}
}
@end
Upvotes: 1