mapbox / mapbox-gl-native

Interactive, thoroughly customizable maps in native Android, iOS, macOS, Node.js, and Qt applications, powered by vector tiles and OpenGL
https://mapbox.com/mobile
Other
4.36k stars 1.33k forks source link

[ios] Attribution button in MGLMapView doesn't present alert controller from modal view controller #8782

Closed cmoulton closed 7 years ago

cmoulton commented 7 years ago

Platform:

iOS

Mapbox SDK version:

3.5.2 via cocoapods

Steps to trigger behavior

  1. Add modally presented VC
  2. Add map view to modally presented VC
  3. Run app, navigate to map view
  4. Tap attribution button

Expected behavior

Attribution UIAlertController displayed

Actual behavior

No change in UI (other than button highlight state). Error shown in console:

Warning: Attempt to present <UIAlertController: 0x7fc73e62f8c0> on 
<MapboxModalAttribution.ViewController: 0x7fc73e40cb00> whose view is not in the window hierarchy!

Demo Project

https://github.com/cmoulton/MapboxModalAttributionTest

Need to set mapbox access token in info.plist to use.

screen shot 2017-04-20 at 10 21 14 am

(Map views in green)

I think the change required is to change this code in MGLMapView.mm (line 1947):

UIViewController *viewController = self.window.rootViewController;
if ([viewController isKindOfClass:[UINavigationController class]]) {
    viewController = [(UINavigationController *)viewController viewControllers].firstObject;
}
[viewController presentViewController:attributionController
                             animated:YES
                           completion:NULL];

To fetch the current top view controller (based on http://stackoverflow.com/a/21848247/90743):

UIViewController *viewController = [UIViewController getTopViewControllerFrom:[self.window.rootViewController topViewController]];
[viewController presentViewController:attributionController
                             animated:YES
                           completion:NULL];

// in UIViewController extension
+ (UIViewController *)getTopViewControllerFrom:(UIViewController *)vc {
    if ([vc isKindOfClass:[UINavigationController class]]) {
        return [UIViewController getTopViewControllerFrom:[((UINavigationController *)vc) visibleViewController]];
    } else if ([vc isKindOfClass:[UITabBarController class]]) {
        return [UIViewController getTopViewControllerFrom:[((UITabBarController *)vc) selectedViewController]];
    } else if (vc.presentedViewController) {
            return [UIViewController getTopViewControllerFrom:vc.presentedViewController];
    }
    return vc;
}
ab-rdarts commented 7 years ago

I have same problem when pressing "i" button on the map which is on modal view controller.

Warning: Attempt to present <UIAlertController: 0x7fc8e20378f0> on <OurViewController: 0x7fc8e20107e0> whose view is not in the window hierarchy!
1ec5 commented 7 years ago

This regression was introduced by #8371. Thank you for the suggested fix, @cmoulton!

/cc @friedbunny

incanus commented 7 years ago

Thanks for the excellent demo project and fix @cmoulton!

kmorey commented 7 years ago

This fixed the issue with the UIAlertController not opening from the attribution button, but the nested telemetry UIAlertController won't open for what appears to be the same issue. I can open a separate issue, but it seems to possibly be the same issue as this one just in a different area.

boundsj commented 7 years ago

Thanks @kmorey. Can you please create a new issue for the telemetry controller specifically?