snappr

Line touches on a line chart no longer need to be precisely touched. Touches nea…

…r a line will trigger the userClickedOnLinePoint and userClickedOnLineKeyPoint delegate methods.
... ... @@ -97,11 +97,13 @@
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchPoint:touches withEvent:event];
[self touchKeyPoint:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchPoint:touches withEvent:event];
[self touchKeyPoint:touches withEvent:event];
}
-(void)touchPoint:(NSSet *)touches withEvent:(UIEvent *)event
... ... @@ -109,26 +111,59 @@
//Get the point user touched
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];
for (int p = _pathPoints.count - 1; p >= 0; p--) {
NSArray *linePointsArray = _pathPoints[p];
for (int i = 0; i < linePointsArray.count - 1; i += 1) {
CGPoint p1 = [linePointsArray[i] CGPointValue];
CGPoint p2 = [linePointsArray[i+1] CGPointValue];
// Closest distance from point to line
float distance = fabsf(((p2.x - p1.x)*(touchPoint.y - p1.y))-((p1.x-touchPoint.x)*(p1.y-p2.y)));
distance /= hypot(p2.x-p1.x, p1.y-p2.y);
if (distance <= 5.0) {
// Conform to delegate parameters, figure out what bezier path this CGPoint belongs to.
for (UIBezierPath *path in _chartPath) {
CGPathRef originalPath = path.CGPath;
CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(originalPath, NULL, 3.0, kCGLineCapRound, kCGLineJoinRound, 3.0);
BOOL pathContainsPoint = CGPathContainsPoint(strokedPath, NULL, touchPoint, NO);
if (pathContainsPoint)
{
BOOL pointContainsPath = CGPathContainsPoint(path.CGPath, NULL, p1, NO);
if (pointContainsPath) {
[_delegate userClickedOnLinePoint:touchPoint lineIndex:[_chartPath indexOfObject:path]];
for (NSArray *linePointsArray in _pathPoints) {
for (NSValue *val in linePointsArray) {
CGPoint p = [val CGPointValue];
if (p.x + 3.0 > touchPoint.x && p.x - 3.0 < touchPoint.x && p.y + 3.0 > touchPoint.y && p.y - 3.0 < touchPoint.y ) {
//Call the delegate and pass the point and index of the point
[_delegate userClickedOnLineKeyPoint:touchPoint lineIndex:[_pathPoints indexOfObject:linePointsArray] andPointIndex:[linePointsArray indexOfObject:val]];
return;
}
}
}
}
}
}
-(void)touchKeyPoint:(NSSet *)touches withEvent:(UIEvent *)event
{
//Get the point user touched
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];
for (int p = _pathPoints.count - 1; p >= 0; p--) {
NSArray *linePointsArray = _pathPoints[p];
for (int i = 0; i < linePointsArray.count - 1; i += 1) {
CGPoint p1 = [linePointsArray[i] CGPointValue];
CGPoint p2 = [linePointsArray[i+1] CGPointValue];
float distanceToP1 = fabsf(hypot(touchPoint.x - p1.x, touchPoint.y - p1.y));
float distanceToP2 = hypot(touchPoint.x - p2.x, touchPoint.y - p2.y);
float distance = MIN(distanceToP1, distanceToP2);
if (distance <= 10.0) {
[_delegate userClickedOnLineKeyPoint:touchPoint
lineIndex:p
andPointIndex:(distance == distanceToP2 ? i+1 : i)];
return;
}
}
}
}
-(void)strokeChart
... ...