[ios] Always set map view reference when annotation view is created. (#5496)

This fixes two issues with annotation views that were exposed when
dragging them:

1) The annotation view's mapView property was not set until it was
moved (in `updateAnnotations:`) so it did not always call its delegate
back about the map view delegate dragging methods. This adds a call to
set the property when an annotation view is created so the delegate
methods are always called.

2) Since the mapView is now always set, a call to the map view's
callout view for selected annotation was added to the annotation
view drag handler. This forces the callout to close and eliminates
an issue where the callout would remain visible as an annotation
was dragged away which had the visual effect of a detached
callout.

To make 2 possible, the map views selected callout view was exposed
in the private header.
This commit is contained in:
Jesse Bounds
2016-06-28 12:07:12 -07:00
committed by GitHub
parent c96b7dae68
commit 16b859ff5f
4 changed files with 42 additions and 7 deletions

View File

@@ -187,7 +187,7 @@
{
CGPoint center = [sender locationInView:sender.view.superview];
[self setCenter:center pitch:self.mapView.camera.pitch];
if (sender.state == UIGestureRecognizerStateEnded) {
self.dragState = MGLAnnotationViewDragStateNone;
}
@@ -206,9 +206,10 @@
if (dragState == MGLAnnotationViewDragStateStarting)
{
[self.mapView.calloutViewForSelectedAnnotation dismissCalloutAnimated:animated];
[self.superview bringSubviewToFront:self];
}
if (dragState == MGLAnnotationViewDragStateEnding)
{
if ([self.mapView.delegate respondsToSelector:@selector(mapView:didDragAnnotationView:toCoordinate:)])
@@ -231,7 +232,7 @@
{
return NO;
}
return YES;
}

View File

@@ -3004,6 +3004,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
if (annotationView)
{
annotationView.annotation = annotation;
annotationView.mapView = self;
CGRect bounds = UIEdgeInsetsInsetRect({ CGPointZero, annotationView.frame.size }, annotationView.alignmentRectInsets);
_largestAnnotationViewSize = CGSizeMake(MAX(_largestAnnotationViewSize.width, CGRectGetWidth(bounds)),

View File

@@ -5,6 +5,9 @@ extern const CGSize MGLAnnotationAccessibilityElementMinimumSize;
@interface MGLMapView (Internal)
/// Currently shown popover representing the selected annotation.
@property (nonatomic) UIView<MGLCalloutView> *calloutViewForSelectedAnnotation;
/** Triggers another render pass even when it is not necessary. */
- (void)setNeedsGLDisplay;

View File

@@ -3,6 +3,17 @@
static NSString * const MGLTestAnnotationReuseIdentifer = @"MGLTestAnnotationReuseIdentifer";
@interface MGLAnnotationView (Test)
@property (nonatomic) MGLMapView *mapView;
@property (nonatomic, readwrite) MGLAnnotationViewDragState dragState;
- (void)setDragState:(MGLAnnotationViewDragState)dragState;
@end
@interface MGLMapView (Test)
@property (nonatomic) UIView<MGLCalloutView> *calloutViewForSelectedAnnotation;
@end
@interface MGLTestAnnotation : NSObject <MGLAnnotation>
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@end
@@ -10,6 +21,19 @@ static NSString * const MGLTestAnnotationReuseIdentifer = @"MGLTestAnnotationReu
@implementation MGLTestAnnotation
@end
@interface MGLTestCalloutView: UIView<MGLCalloutView>
@property (nonatomic) BOOL didCallDismissCalloutAnimated;
@end
@implementation MGLTestCalloutView
- (void)dismissCalloutAnimated:(BOOL)animated
{
_didCallDismissCalloutAnimated = YES;
}
@end
@interface MGLAnnotationViewTests : XCTestCase <MGLMapViewDelegate>
@property (nonatomic) XCTestExpectation *expectation;
@property (nonatomic) MGLMapView *mapView;
@@ -28,15 +52,21 @@ static NSString * const MGLTestAnnotationReuseIdentifer = @"MGLTestAnnotationReu
- (void)testAnnotationView
{
_expectation = [self expectationWithDescription:@"annotation property"];
MGLTestAnnotation *annotation = [[MGLTestAnnotation alloc] init];
[_mapView addAnnotation:annotation];
[self waitForExpectationsWithTimeout:1 handler:nil];
XCTAssert(_mapView.annotations.count == 1, @"number of annotations should be 1");
XCTAssertNotNil(_annotationView.annotation, @"annotation property should not be nil");
XCTAssertNotNil(_annotationView.mapView, @"mapView property should not be nil");
MGLTestCalloutView *testCalloutView = [[MGLTestCalloutView alloc] init];
_mapView.calloutViewForSelectedAnnotation = testCalloutView;
_annotationView.dragState = MGLAnnotationViewDragStateStarting;
XCTAssertTrue(testCalloutView.didCallDismissCalloutAnimated, @"callout view was not dismissed");
[_mapView removeAnnotation:_annotationView.annotation];
XCTAssert(_mapView.annotations.count == 0, @"number of annotations should be 0");