@@ -61,33 +61,16 @@ @interface FLTUrlLauncherPlugin ()
6161
6262@end
6363
64- @interface FLTUrlLauncherPlugin ()
65-
66- @property (strong , nonatomic ) UIViewController *viewController;
67-
68- @end
69-
7064@implementation FLTUrlLauncherPlugin
7165
7266+ (void )registerWithRegistrar : (NSObject <FlutterPluginRegistrar> *)registrar {
7367 FlutterMethodChannel *channel =
7468 [FlutterMethodChannel methodChannelWithName: @" plugins.flutter.io/url_launcher"
7569 binaryMessenger: registrar.messenger];
76- UIViewController *viewController =
77- [UIApplication sharedApplication ].delegate .window .rootViewController ;
78- FLTUrlLauncherPlugin *plugin =
79- [[FLTUrlLauncherPlugin alloc ] initWithViewController: viewController];
70+ FLTUrlLauncherPlugin *plugin = [[FLTUrlLauncherPlugin alloc ] init ];
8071 [registrar addMethodCallDelegate: plugin channel: channel];
8172}
8273
83- - (instancetype )initWithViewController : (UIViewController *)viewController {
84- self = [super init ];
85- if (self) {
86- self.viewController = viewController;
87- }
88- return self;
89- }
90-
9174- (void )handleMethodCall : (FlutterMethodCall *)call result : (FlutterResult)result {
9275 NSString *url = call.arguments [@" url" ];
9376 if ([@" canLaunch" isEqualToString: call.method]) {
@@ -153,9 +136,9 @@ - (void)launchURLInVC:(NSString *)urlString result:(FlutterResult)result API_AVA
153136 self.currentSession .didFinish = ^(void ) {
154137 weakSelf.currentSession = nil ;
155138 };
156- [self .viewController presentViewController: self .currentSession.safari
157- animated: YES
158- completion: nil ];
139+ [self .topViewController presentViewController: self .currentSession.safari
140+ animated: YES
141+ completion: nil ];
159142}
160143
161144- (void )closeWebViewWithResult : (FlutterResult)result API_AVAILABLE(ios(9.0 )) {
@@ -165,4 +148,36 @@ - (void)closeWebViewWithResult:(FlutterResult)result API_AVAILABLE(ios(9.0)) {
165148 result (nil );
166149}
167150
151+ - (UIViewController *)topViewController {
152+ return [self topViewControllerFromViewController: [UIApplication sharedApplication ]
153+ .keyWindow.rootViewController];
154+ }
155+
156+ /* *
157+ * This method recursively iterate through the view hierarchy
158+ * to return the top most view controller.
159+ *
160+ * It supports the following scenarios:
161+ *
162+ * - The view controller is presenting another view.
163+ * - The view controller is a UINavigationController.
164+ * - The view controller is a UITabBarController.
165+ *
166+ * @return The top most view controller.
167+ */
168+ - (UIViewController *)topViewControllerFromViewController : (UIViewController *)viewController {
169+ if ([viewController isKindOfClass: [UINavigationController class ]]) {
170+ UINavigationController *navigationController = (UINavigationController *)viewController;
171+ return [self
172+ topViewControllerFromViewController: [navigationController.viewControllers lastObject ]];
173+ }
174+ if ([viewController isKindOfClass: [UITabBarController class ]]) {
175+ UITabBarController *tabController = (UITabBarController *)viewController;
176+ return [self topViewControllerFromViewController: tabController.selectedViewController];
177+ }
178+ if (viewController.presentedViewController ) {
179+ return [self topViewControllerFromViewController: viewController.presentedViewController];
180+ }
181+ return viewController;
182+ }
168183@end
0 commit comments