Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

fixes #8782: properly show attribution in modal hierarchies #8837

Merged
merged 7 commits into from
May 2, 2017

Conversation

incanus
Copy link
Contributor

@incanus incanus commented Apr 27, 2017

Incorporates @cmoulton's fix from #8782, which we (@jmkiley and I) tested and debugged. We use three of the four code paths in the UIViewController category (all but tab view controller) in the process of finding the true top view controller from which to display the attribution sheet. Even with not using the tab bar controller path, we though it best to leave it in since it makes this method truly complete and generically useful.

Despite being one method, we though it best to start a UIViewController category here as a template for future use and a way to keep MGLMapView.mm trim, and this can indeed be a class method since it doesn't depend on any state.

Also did a little category import re-alphabetization while in there 😉

@incanus incanus added this to the ios-v3.5.3 milestone Apr 27, 2017
@incanus incanus requested review from boundsj, friedbunny and 1ec5 April 27, 2017 18:07
}
viewController = [UIViewController getTopViewControllerFrom:viewController];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be conditional or always reassign line:1952?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's always if it's indeed a navigation controller, since a navigation controller with out any view controllers doesn't make any sense. Or am I misunderstanding you @frederoni?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh nvm, I was unable to parse this. It looks good. 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be wrong but it seems like you can remove the check for topViewController so maybe this can now be:

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

The category seems like it'll work out the visibleViewController (modal or otherwise).

If that works and depending on what you decide to do about https://github.com/mapbox/mapbox-gl-native/pull/8837/files#r113819069, maybe this could end up like:

[[self.window.rootViewController topMostViewController] presentViewController:attributionController
                                                                     animated:YES
                                                                   completion:NULL];

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, missed this in between some work on 4903db6 @boundsj. Basically, that's what I was already working on 😄.


@interface UIViewController (MGLAdditions)

+ (UIViewController *)getTopViewControllerFrom:(UIViewController *)viewController;
Copy link
Contributor

@frederoni frederoni Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Prefixed method names in categories on framework classes.
Btw, do we need the viewController arg when we have access to self?

+[UIViewController(MGLAdditions) topViewController] would conflict with -[UINavigationViewController topViewController] but how about +[UIViewController(MGLAdditions) mgl_topMostViewController]?

-edited-
Just noticed 🙈

and this can indeed be a class method since it doesn't depend on any state.

However, get in method names are only used when returning objects or values indirectly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point re: get. Will fix. This came from the user's suggestion. @jmkiley and I discussed this method name a bit and figured we'd get some more input first.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


@implementation UIViewController (MGLAdditions)

+ (UIViewController *)getTopViewControllerFrom:(UIViewController *)viewController
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can indeed be a class method since it doesn't depend on any state

That’s true as far as the current implementation goes. However, it would be possible to express this method in a different way, so that a UIViewController knows how to return its topmost containing view controller: -topmostViewController or perhaps -rootViewController.

@incanus
Copy link
Contributor Author

incanus commented Apr 28, 2017

In 4903db6 I get rid of the explicit inline check for topViewController and just rely on the category method's visibleViewController, which should capture this. Per the docs (emphasis mine):

The currently visible view can belong either to the view controller at the top of the navigation stack or to a view controller that was presented modally on top of the navigation controller itself.


@interface UIViewController (MGLAdditions)

+ (UIViewController *)mgl_topMostViewControllerInHierarchyWith:(UIViewController *)viewController;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Objective-C, a selector piece (mgl_topMostViewControllerInHierarchyWith:) should always end with a noun, not a preposition.

This should be an instance method or read-only property named mgl_topmostViewController. The return value is related to viewController, not the UIViewController class as a whole. One might expect this class method, as written, to be a factory method for creating UIViewControllers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also prefer this to be an instance method to support being able to call it like in #8837 (comment). Otherwise I think this is 👍

@tobrun tobrun added the iOS Mapbox Maps SDK for iOS label Apr 28, 2017
@boundsj
Copy link
Contributor

boundsj commented Apr 28, 2017

@incanus just noticed that this is against master but in the ios-v3.5.3 milestone. Please plan to cherry pick to the release-ios-v3.5.0-android-v5.0.0 or retarget this PR (in general, we push commits to the release branch and then merge it back to master rather than cherry picking but it does not really matter in this case)

@jmkiley jmkiley force-pushed the 8782-modal-attribution branch from f718d4d to 4903db6 Compare May 1, 2017 19:13
{
if ([viewController isKindOfClass:[UINavigationController class]])
{
return [self mgl_topMostViewControllerInHierarchyWith:[(UINavigationController *)viewController visibleViewController]];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of passing in visibleViewController, call mgl_topMostViewController on visibleViewController. This method doesn't need to take any parameters.

@jmkiley jmkiley force-pushed the 8782-modal-attribution branch from 824d269 to 8e17f5a Compare May 2, 2017 19:02
@jmkiley
Copy link
Contributor

jmkiley commented May 2, 2017

I think I addressed @1ec5's feedback in 8e17f5a, but please let me know if I missed anything!

Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for iterating – this looks great!

}
else if ([self isKindOfClass:[UITabBarController class]])
{
return [[((UITabBarController *)self) selectedViewController] mgl_topMostViewController];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: extraneous parentheses around self.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Just fixed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
iOS Mapbox Maps SDK for iOS
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants