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.
Showing
1 changed file
with
47 additions
and
12 deletions
| @@ -97,11 +97,13 @@ | @@ -97,11 +97,13 @@ | ||
| 97 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event | 97 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event |
| 98 | { | 98 | { |
| 99 | [self touchPoint:touches withEvent:event]; | 99 | [self touchPoint:touches withEvent:event]; |
| 100 | + [self touchKeyPoint:touches withEvent:event]; | ||
| 100 | } | 101 | } |
| 101 | 102 | ||
| 102 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event | 103 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event |
| 103 | { | 104 | { |
| 104 | [self touchPoint:touches withEvent:event]; | 105 | [self touchPoint:touches withEvent:event]; |
| 106 | + [self touchKeyPoint:touches withEvent:event]; | ||
| 105 | } | 107 | } |
| 106 | 108 | ||
| 107 | -(void)touchPoint:(NSSet *)touches withEvent:(UIEvent *)event | 109 | -(void)touchPoint:(NSSet *)touches withEvent:(UIEvent *)event |
| @@ -109,26 +111,59 @@ | @@ -109,26 +111,59 @@ | ||
| 109 | //Get the point user touched | 111 | //Get the point user touched |
| 110 | UITouch *touch = [touches anyObject]; | 112 | UITouch *touch = [touches anyObject]; |
| 111 | CGPoint touchPoint = [touch locationInView:self]; | 113 | CGPoint touchPoint = [touch locationInView:self]; |
| 114 | + | ||
| 115 | + for (int p = _pathPoints.count - 1; p >= 0; p--) { | ||
| 116 | + NSArray *linePointsArray = _pathPoints[p]; | ||
| 117 | + | ||
| 118 | + for (int i = 0; i < linePointsArray.count - 1; i += 1) { | ||
| 119 | + CGPoint p1 = [linePointsArray[i] CGPointValue]; | ||
| 120 | + CGPoint p2 = [linePointsArray[i+1] CGPointValue]; | ||
| 121 | + | ||
| 122 | + // Closest distance from point to line | ||
| 123 | + float distance = fabsf(((p2.x - p1.x)*(touchPoint.y - p1.y))-((p1.x-touchPoint.x)*(p1.y-p2.y))); | ||
| 124 | + distance /= hypot(p2.x-p1.x, p1.y-p2.y); | ||
| 125 | + | ||
| 126 | + if (distance <= 5.0) { | ||
| 127 | + // Conform to delegate parameters, figure out what bezier path this CGPoint belongs to. | ||
| 112 | for (UIBezierPath *path in _chartPath) { | 128 | for (UIBezierPath *path in _chartPath) { |
| 113 | - CGPathRef originalPath = path.CGPath; | 129 | + BOOL pointContainsPath = CGPathContainsPoint(path.CGPath, NULL, p1, NO); |
| 114 | - CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(originalPath, NULL, 3.0, kCGLineCapRound, kCGLineJoinRound, 3.0); | 130 | + |
| 115 | - BOOL pathContainsPoint = CGPathContainsPoint(strokedPath, NULL, touchPoint, NO); | 131 | + if (pointContainsPath) { |
| 116 | - if (pathContainsPoint) | ||
| 117 | - { | ||
| 118 | [_delegate userClickedOnLinePoint:touchPoint lineIndex:[_chartPath indexOfObject:path]]; | 132 | [_delegate userClickedOnLinePoint:touchPoint lineIndex:[_chartPath indexOfObject:path]]; |
| 119 | - for (NSArray *linePointsArray in _pathPoints) { | 133 | + return; |
| 120 | - for (NSValue *val in linePointsArray) { | ||
| 121 | - CGPoint p = [val CGPointValue]; | ||
| 122 | - 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 ) { | ||
| 123 | - //Call the delegate and pass the point and index of the point | ||
| 124 | - [_delegate userClickedOnLineKeyPoint:touchPoint lineIndex:[_pathPoints indexOfObject:linePointsArray] andPointIndex:[linePointsArray indexOfObject:val]]; | ||
| 125 | } | 134 | } |
| 126 | } | 135 | } |
| 127 | } | 136 | } |
| 128 | - | ||
| 129 | } | 137 | } |
| 130 | } | 138 | } |
| 139 | +} | ||
| 140 | + | ||
| 141 | +-(void)touchKeyPoint:(NSSet *)touches withEvent:(UIEvent *)event | ||
| 142 | +{ | ||
| 143 | + //Get the point user touched | ||
| 144 | + UITouch *touch = [touches anyObject]; | ||
| 145 | + CGPoint touchPoint = [touch locationInView:self]; | ||
| 146 | + | ||
| 147 | + for (int p = _pathPoints.count - 1; p >= 0; p--) { | ||
| 148 | + NSArray *linePointsArray = _pathPoints[p]; | ||
| 149 | + | ||
| 150 | + for (int i = 0; i < linePointsArray.count - 1; i += 1) { | ||
| 151 | + CGPoint p1 = [linePointsArray[i] CGPointValue]; | ||
| 152 | + CGPoint p2 = [linePointsArray[i+1] CGPointValue]; | ||
| 131 | 153 | ||
| 154 | + float distanceToP1 = fabsf(hypot(touchPoint.x - p1.x, touchPoint.y - p1.y)); | ||
| 155 | + float distanceToP2 = hypot(touchPoint.x - p2.x, touchPoint.y - p2.y); | ||
| 156 | + | ||
| 157 | + float distance = MIN(distanceToP1, distanceToP2); | ||
| 158 | + | ||
| 159 | + if (distance <= 10.0) { | ||
| 160 | + [_delegate userClickedOnLineKeyPoint:touchPoint | ||
| 161 | + lineIndex:p | ||
| 162 | + andPointIndex:(distance == distanceToP2 ? i+1 : i)]; | ||
| 163 | + return; | ||
| 164 | + } | ||
| 165 | + } | ||
| 166 | + } | ||
| 132 | } | 167 | } |
| 133 | 168 | ||
| 134 | -(void)strokeChart | 169 | -(void)strokeChart |
-
Please register or login to post a comment