summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin R. Miller <incanus@codesorcery.net>2015-03-27 11:12:50 -0700
committerJustin R. Miller <incanus@codesorcery.net>2015-03-27 11:12:50 -0700
commit215a7c4b2b1222f953efaf814041253b1a561725 (patch)
treea02532ff052e2717adddfa11c9f9698db9b39f2b
parent2822dd5b623e2d12469398a49d4b019645d0d47e (diff)
downloadqtlocation-mapboxgl-215a7c4b2b1222f953efaf814041253b1a561725.tar.gz
only recognize the end state of single taps
-rw-r--r--platform/ios/MGLMapView.mm175
1 files changed, 89 insertions, 86 deletions
diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm
index 5bf981bda3..200fb02fa7 100644
--- a/platform/ios/MGLMapView.mm
+++ b/platform/ios/MGLMapView.mm
@@ -743,124 +743,127 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
- (void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTap
{
- [self trackGestureEvent:MGLEventGestureSingleTap forRecognizer:singleTap];
-
- CGPoint tapPoint = [singleTap locationInView:self];
-
- if (self.userLocationVisible && ! [self.selectedAnnotation isEqual:self.userLocation])
+ if (singleTap.state == UIGestureRecognizerStateEnded)
{
- CGRect userLocationRect = CGRectMake(tapPoint.x - 15, tapPoint.y - 15, 30, 30);
+ [self trackGestureEvent:MGLEventGestureSingleTap forRecognizer:singleTap];
+
+ CGPoint tapPoint = [singleTap locationInView:self];
- if (CGRectContainsPoint(userLocationRect, [self convertCoordinate:self.userLocation.coordinate toPointToView:self]))
+ if (self.userLocationVisible && ! [self.selectedAnnotation isEqual:self.userLocation])
{
- [self selectAnnotation:self.userLocation animated:YES];
- return;
- }
- }
+ CGRect userLocationRect = CGRectMake(tapPoint.x - 15, tapPoint.y - 15, 30, 30);
- // tolerances based on touch size & typical marker aspect ratio
- CGFloat toleranceWidth = 40;
- CGFloat toleranceHeight = 60;
+ if (CGRectContainsPoint(userLocationRect, [self convertCoordinate:self.userLocation.coordinate toPointToView:self]))
+ {
+ [self selectAnnotation:self.userLocation animated:YES];
+ return;
+ }
+ }
- // setup a recognition area weighted 2/3 of the way above the point to account for average marker imagery
- CGRect tapRect = CGRectMake(tapPoint.x - toleranceWidth / 2, tapPoint.y - 2 * toleranceHeight / 3, toleranceWidth, toleranceHeight);
- CGPoint tapRectLowerLeft = CGPointMake(tapRect.origin.x, tapRect.origin.y + tapRect.size.height);
- CGPoint tapRectUpperLeft = CGPointMake(tapRect.origin.x, tapRect.origin.y);
- CGPoint tapRectUpperRight = CGPointMake(tapRect.origin.x + tapRect.size.width, tapRect.origin.y);
- CGPoint tapRectLowerRight = CGPointMake(tapRect.origin.x + tapRect.size.width, tapRect.origin.y + tapRect.size.height);
+ // tolerances based on touch size & typical marker aspect ratio
+ CGFloat toleranceWidth = 40;
+ CGFloat toleranceHeight = 60;
- // figure out what that means in coordinate space
- CLLocationCoordinate2D coordinate;
- mbgl::LatLngBounds tapBounds;
+ // setup a recognition area weighted 2/3 of the way above the point to account for average marker imagery
+ CGRect tapRect = CGRectMake(tapPoint.x - toleranceWidth / 2, tapPoint.y - 2 * toleranceHeight / 3, toleranceWidth, toleranceHeight);
+ CGPoint tapRectLowerLeft = CGPointMake(tapRect.origin.x, tapRect.origin.y + tapRect.size.height);
+ CGPoint tapRectUpperLeft = CGPointMake(tapRect.origin.x, tapRect.origin.y);
+ CGPoint tapRectUpperRight = CGPointMake(tapRect.origin.x + tapRect.size.width, tapRect.origin.y);
+ CGPoint tapRectLowerRight = CGPointMake(tapRect.origin.x + tapRect.size.width, tapRect.origin.y + tapRect.size.height);
- coordinate = [self convertPoint:tapRectLowerLeft toCoordinateFromView:self];
- tapBounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
+ // figure out what that means in coordinate space
+ CLLocationCoordinate2D coordinate;
+ mbgl::LatLngBounds tapBounds;
- coordinate = [self convertPoint:tapRectUpperLeft toCoordinateFromView:self];
- tapBounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
+ coordinate = [self convertPoint:tapRectLowerLeft toCoordinateFromView:self];
+ tapBounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
- coordinate = [self convertPoint:tapRectUpperRight toCoordinateFromView:self];
- tapBounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
+ coordinate = [self convertPoint:tapRectUpperLeft toCoordinateFromView:self];
+ tapBounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
- coordinate = [self convertPoint:tapRectLowerRight toCoordinateFromView:self];
- tapBounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
+ coordinate = [self convertPoint:tapRectUpperRight toCoordinateFromView:self];
+ tapBounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
- // query for nearby annotations
- std::vector<uint32_t> nearbyAnnotations = mbglMap->getAnnotationsInBounds(tapBounds);
+ coordinate = [self convertPoint:tapRectLowerRight toCoordinateFromView:self];
+ tapBounds.extend(mbgl::LatLng(coordinate.latitude, coordinate.longitude));
- int32_t newSelectedAnnotationID = -1;
+ // query for nearby annotations
+ std::vector<uint32_t> nearbyAnnotations = mbglMap->getAnnotationsInBounds(tapBounds);
- if (nearbyAnnotations.size())
- {
- // there is at least one nearby annotation; select one
- //
- // first, sort for comparison and iteration
- std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end());
+ int32_t newSelectedAnnotationID = -1;
- if (nearbyAnnotations == self.annotationsNearbyLastTap)
+ if (nearbyAnnotations.size())
{
- // the selection candidates haven't changed; cycle through them
- if (self.selectedAnnotation &&
- [[[self.annotationIDsByAnnotation objectForKey:self.selectedAnnotation]
- objectForKey:MGLAnnotationIDKey] unsignedIntValue] == self.annotationsNearbyLastTap.back())
- {
- // the selected annotation is the last in the set; cycle back to the first
- // note: this could be the selected annotation if only one in set
- newSelectedAnnotationID = self.annotationsNearbyLastTap.front();
- }
- else if (self.selectedAnnotation)
+ // there is at least one nearby annotation; select one
+ //
+ // first, sort for comparison and iteration
+ std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end());
+
+ if (nearbyAnnotations == self.annotationsNearbyLastTap)
{
- // otherwise increment the selection through the candidates
- uint32_t currentID = [[[self.annotationIDsByAnnotation objectForKey:self.selectedAnnotation] objectForKey:MGLAnnotationIDKey] unsignedIntValue];
- auto result = std::find(self.annotationsNearbyLastTap.begin(), self.annotationsNearbyLastTap.end(), currentID);
- auto distance = std::distance(self.annotationsNearbyLastTap.begin(), result);
- newSelectedAnnotationID = self.annotationsNearbyLastTap[distance + 1];
+ // the selection candidates haven't changed; cycle through them
+ if (self.selectedAnnotation &&
+ [[[self.annotationIDsByAnnotation objectForKey:self.selectedAnnotation]
+ objectForKey:MGLAnnotationIDKey] unsignedIntValue] == self.annotationsNearbyLastTap.back())
+ {
+ // the selected annotation is the last in the set; cycle back to the first
+ // note: this could be the selected annotation if only one in set
+ newSelectedAnnotationID = self.annotationsNearbyLastTap.front();
+ }
+ else if (self.selectedAnnotation)
+ {
+ // otherwise increment the selection through the candidates
+ uint32_t currentID = [[[self.annotationIDsByAnnotation objectForKey:self.selectedAnnotation] objectForKey:MGLAnnotationIDKey] unsignedIntValue];
+ auto result = std::find(self.annotationsNearbyLastTap.begin(), self.annotationsNearbyLastTap.end(), currentID);
+ auto distance = std::distance(self.annotationsNearbyLastTap.begin(), result);
+ newSelectedAnnotationID = self.annotationsNearbyLastTap[distance + 1];
+ }
+ else
+ {
+ // no current selection; select the first one
+ newSelectedAnnotationID = self.annotationsNearbyLastTap.front();
+ }
}
else
{
- // no current selection; select the first one
+ // start tracking a new set of nearby annotations
+ self.annotationsNearbyLastTap = nearbyAnnotations;
+
+ // select the first one
newSelectedAnnotationID = self.annotationsNearbyLastTap.front();
}
}
else
{
- // start tracking a new set of nearby annotations
- self.annotationsNearbyLastTap = nearbyAnnotations;
-
- // select the first one
- newSelectedAnnotationID = self.annotationsNearbyLastTap.front();
+ // there are no nearby annotations; deselect if necessary
+ newSelectedAnnotationID = -1;
}
- }
- else
- {
- // there are no nearby annotations; deselect if necessary
- newSelectedAnnotationID = -1;
- }
-
- if (newSelectedAnnotationID >= 0)
- {
- // find & select model object for selection
- NSEnumerator *enumerator = self.annotationIDsByAnnotation.keyEnumerator;
- while (id <MGLAnnotation> annotation = enumerator.nextObject)
+ if (newSelectedAnnotationID >= 0)
{
- if ([[[self.annotationIDsByAnnotation objectForKey:annotation] objectForKey:MGLAnnotationIDKey] integerValue] == newSelectedAnnotationID)
+ // find & select model object for selection
+ NSEnumerator *enumerator = self.annotationIDsByAnnotation.keyEnumerator;
+
+ while (id <MGLAnnotation> annotation = enumerator.nextObject)
{
- // only change selection status if not the currently selected annotation
- if ( ! [annotation isEqual:self.selectedAnnotation])
+ if ([[[self.annotationIDsByAnnotation objectForKey:annotation] objectForKey:MGLAnnotationIDKey] integerValue] == newSelectedAnnotationID)
{
- [self selectAnnotation:annotation animated:YES];
- }
+ // only change selection status if not the currently selected annotation
+ if ( ! [annotation isEqual:self.selectedAnnotation])
+ {
+ [self selectAnnotation:annotation animated:YES];
+ }
- // either way, we should stop enumerating
- break;
+ // either way, we should stop enumerating
+ break;
+ }
}
}
- }
- else
- {
- // deselect any selected annotation
- if (self.selectedAnnotation) [self deselectAnnotation:self.selectedAnnotation animated:YES];
+ else
+ {
+ // deselect any selected annotation
+ if (self.selectedAnnotation) [self deselectAnnotation:self.selectedAnnotation animated:YES];
+ }
}
}