Mapbox-gl-native: MGLMapView sets the tint color of annotation views when its tint color is changed.

Created on 24 Mar 2017  路  3Comments  路  Source: mapbox/mapbox-gl-native

Platform:
iOS 9/10 - Xcode 8.2
Mapbox SDK version:
iOS SDK 3.5 (was duplicatable on 3.4.2)

Example app of the bug has been created here: https://github.com/MattKiazyk/mglannotationbug

We are using a custom annotation view that uses a bunch of UIImageViews to create a pin that has a tint color on the background image, as well as a overlapping image that has a white tint color. When we tap on the callout and open up a new view, the annotationView is resetting it's tint color.

jeff recording - mar 24 2017 10 00 16 02 am

Steps to trigger behavior

  1. Tap on orange pin, and tap the callout to open a new popup
  2. Close the popup
  3. The original orange pin, is now tinted blue

Expected behavior

I'm expecting the annotation view to keep my original tint color.
screenshot 2017-03-24 11 07 27

Actual behavior

You'll see from the screenshots below that the annotationView (blue pin) has the proper images, however is just tinted to blue instead of like the screenshot above

screenshot 2017-03-24 11 06 41

annotations bug iOS

All 3 comments

Hi @MattKiazyk thanks for the report and for the repro example!

In https://github.com/mapbox/mapbox-gl-native/pull/1082, logic was added to keep the tint color of UIView's associated with map view in sync with the application. MGLAnnotationView came along much later in https://github.com/mapbox/mapbox-gl-native/pull/4801 and the change from https://github.com/mapbox/mapbox-gl-native/pull/1082 continues to change the tint color of all subviews of the map, now including annotation views.

A similar issue to this was ticketed in https://github.com/mapbox/mapbox-gl-native/issues/6023. But, that issue was about arbitrary views that may be in the map view hierarchy. I think it would make sense to guard against changing the tint color of annotation views specifically since that is probably going a step too far and would normally be unhelpful.

In this particular case, the tint color is changed because UIKit uses tint color to dim the views behind PopupViewController (a class in the attached repro) when it is presented. For now, some workarounds to consider could be subclassing UIImageView so tint color can be set selectively (i.e. ignored in the presentation case) or setting the map view's tintAdjustmentMode to UIViewTintAdjustmentModeNormal in mapView:didAddAnnotationViews:.

cc @jmkiley @friedbunny

Thank you for quick response @boundsj - and the workaround/change to make it work. I can confirm it works as it's now intended!

Paired with @jmkiley on this and created both a repro and a fix.

Repro requires the iPad device idiom (to allow form-based modals, which cues the system dimming tint) and for you to pick the 100/1000/10000 annotation view debug option. Patch creates annotation views with red-tinted buttons, then presents a form modal on a timer after these are added, then auto-dismisses, which cues the system reversal of the dimming tint. At present, this reverts the annotation view buttons to the SDK-default blueish tint, not the original, custom red.

```diff
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index 70271c02b..c82cc00d1 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -716,6 +716,19 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
});
}
});
+

  • NSAssert([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad, @"test condition requires iPad");
  • dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  • UIViewController *viewController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
  • viewController.view.backgroundColor = [UIColor purpleColor];
  • UINavigationController *wrapper = [[UINavigationController alloc] initWithRootViewController:viewController];
  • wrapper.modalPresentationStyle = UIModalPresentationFormSheet;
  • [self presentViewController:wrapper animated:YES completion:^{
  • dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  • [wrapper dismissViewControllerAnimated:NO completion:nil];
  • });
  • }];
  • });
    }
  • (void)animateAnnotationView
    @@ -1628,28 +1641,35 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
    return nil;
    }

    • MBXAnnotationView *annotationView = (MBXAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:MBXViewControllerAnnotationViewReuseIdentifer];
    • if (!annotationView)
    • {
    • annotationView = [[MBXAnnotationView alloc] initWithReuseIdentifier:MBXViewControllerAnnotationViewReuseIdentifer];
    • annotationView.frame = CGRectMake(0, 0, 10, 10);
    • annotationView.backgroundColor = [UIColor whiteColor];
      -
    • // Note that having two long press gesture recognizers on overlapping
    • // views (self.view & annotationView) will cause weird behaviour.
    • // Comment out the pin dropping functionality in the handleLongPress:
    • // method in this class to make draggable annotation views play nice.
    • annotationView.draggable = YES;
      -
    • // Uncomment to force annotation view to maintain a constant size when
    • // the map is tilted. By default, annotation views will shrink and grow
    • // as they move towards and away from the horizon. Relatedly, annotations
    • // backed by GL sprites currently ONLY scale with viewing distance.
    • // annotationView.scalesWithViewingDistance = NO;
    • } else {
    • // orange indicates that the annotation view was reused
    • annotationView.backgroundColor = [UIColor orangeColor];
    • }
      +// MBXAnnotationView *annotationView = (MBXAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:MBXViewControllerAnnotationViewReuseIdentifer];
      +// if (!annotationView)
      +// {
      +// annotationView = [[MBXAnnotationView alloc] initWithReuseIdentifier:MBXViewControllerAnnotationViewReuseIdentifer];
      +// annotationView.frame = CGRectMake(0, 0, 10, 10);
      +// annotationView.backgroundColor = [UIColor whiteColor];
      +//
      +// // Note that having two long press gesture recognizers on overlapping
      +// // views (self.view & annotationView) will cause weird behaviour.
      +// // Comment out the pin dropping functionality in the handleLongPress:
      +// // method in this class to make draggable annotation views play nice.
      +// annotationView.draggable = YES;
      +//
      +// // Uncomment to force annotation view to maintain a constant size when
      +// // the map is tilted. By default, annotation views will shrink and grow
      +// // as they move towards and away from the horizon. Relatedly, annotations
      +// // backed by GL sprites currently ONLY scale with viewing distance.
      +// // annotationView.scalesWithViewingDistance = NO;
      +// } else {
      +// // orange indicates that the annotation view was reused
      +// annotationView.backgroundColor = [UIColor orangeColor];
      +// }
    • MGLAnnotationView *annotationView = [[MGLAnnotationView alloc] initWithReuseIdentifier:@"foo"];
    • annotationView.frame = CGRectMake(0, 0, 50, 50);
    • annotationView.backgroundColor = [UIColor yellowColor];
    • UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoLight];
    • button.tintColor = [UIColor redColor];
    • [annotationView addSubview:button];
    • button.center = CGPointMake(25, 25);
      return annotationView;
      }
      ```

simulator screen shot apr 20 2017 11 14 16 am

Proposed one-line fix is over in https://github.com/mapbox/mapbox-gl-native/pull/8789.

Was this page helpful?
0 / 5 - 0 ratings