diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm index cba52ffdc47aa..257cb4420c776 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm @@ -241,12 +241,15 @@ - (void)popSystemNavigator:(BOOL)isAnimated { // in the navigation hierarchy. // It's also possible in an Add2App scenario that the FlutterViewController was presented // outside the context of a UINavigationController, and still wants to be popped. - UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController; - if ([viewController isKindOfClass:[UINavigationController class]]) { - [((UINavigationController*)viewController) popViewControllerAnimated:isAnimated]; + + UIViewController* engineViewController = [_engine.get() viewController]; + UINavigationController* navigationController = [engineViewController navigationController]; + if (navigationController) { + [navigationController popViewControllerAnimated:isAnimated]; } else { - auto engineViewController = static_cast([_engine.get() viewController]); - if (engineViewController != viewController) { + UIViewController* rootViewController = + [UIApplication sharedApplication].keyWindow.rootViewController; + if (engineViewController != rootViewController) { [engineViewController dismissViewControllerAnimated:isAnimated completion:nil]; } } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm index 691d627c334d7..23c7d2f942aee 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm @@ -7,6 +7,7 @@ #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" +#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h" #import "flutter/shell/platform/darwin/ios/platform_view_ios.h" @@ -48,4 +49,32 @@ - (void)testHasStrings { XCTAssertEqual(value, true); } +- (void)testPopSystemNavigator { + FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; + [engine runWithEntrypoint:nil]; + FlutterViewController* flutterViewController = + [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil]; + UINavigationController* navigationController = + [[UINavigationController alloc] initWithRootViewController:flutterViewController]; + UITabBarController* tabBarController = [[UITabBarController alloc] init]; + tabBarController.viewControllers = @[ navigationController ]; + std::unique_ptr> _weakFactory = + std::make_unique>(engine); + FlutterPlatformPlugin* plugin = + [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()]; + + id navigationControllerMock = OCMPartialMock(navigationController); + OCMStub([navigationControllerMock popViewControllerAnimated:YES]); + // Set some string to the pasteboard. + __block bool calledSet = false; + FlutterResult resultSet = ^(id result) { + calledSet = true; + }; + FlutterMethodCall* methodCallSet = + [FlutterMethodCall methodCallWithMethodName:@"SystemNavigator.pop" arguments:@(YES)]; + [plugin handleMethodCall:methodCallSet result:resultSet]; + XCTAssertEqual(calledSet, true); + OCMVerify([navigationControllerMock popViewControllerAnimated:YES]); +} + @end