From 5e246309e006aebe934fe9273253702f29e5d38e Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Dec 2023 18:33:02 +0100 Subject: [PATCH 1/4] Fix simple scenario when top-level vc is dismissed --- ios/RNSScreenStack.mm | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index be79f080d0..1361862ac5 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -501,15 +501,27 @@ - (void)setModalViewControllers:(NSArray *)controllers } } - // changeRootController does not have presentedViewController but it does not mean that no modals are in presentation, - // so we need to find top-level controller manually + // changeRootController does not have presentedViewController but it does not mean that no modals are in presentation; + // modals could be presented by another stack (nested / outer), third-party view controller or they could be using + // UIModalPresentationCurrentContext / UIModalPresentationOverCurrentContext presentation styles; in the last case + // for some reason system asks top-level (react root) vc to present instead of our stack, despite the fact that + // `definesPresentationContext` returns `YES` for UINavigationController. + // So we first need to find top-level controller manually: UIViewController *reactRootVc = [self findReactRootViewController]; UIViewController *topMostVc = [RNSScreenStackView findTopMostPresentedViewControllerFromViewController:reactRootVc]; if (topMostVc != reactRootVc) { changeRootController = topMostVc; + + // Here we handle just the simplest case where the top level VC was dismissed. In any more complex + // scenario we will still have problems, see: https://github.com/software-mansion/react-native-screens/issues/1813 + if ([_presentedModals containsObject:topMostVc] && ![controllers containsObject:topMostVc]) { + [changeRootController dismissViewControllerAnimated:YES completion:finish]; + return; + } } + // We didn't detect any controllers for dismissal, thus we start presenting new vcs finish(); } From 466cef495f8b3e43f372e7639399b997393dfd5b Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Dec 2023 18:40:40 +0100 Subject: [PATCH 2/4] Add code to Example application that will allow for testing this change --- Example/src/screens/Modals.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Example/src/screens/Modals.tsx b/Example/src/screens/Modals.tsx index 47badffbc5..a98f7c3bae 100644 --- a/Example/src/screens/Modals.tsx +++ b/Example/src/screens/Modals.tsx @@ -11,6 +11,7 @@ type StackParamList = { Modal: undefined; FullscreenModal: undefined; Alert: undefined; + ContainedModal: undefined; }; interface MainScreenProps { @@ -25,6 +26,10 @@ const MainScreen = ({ navigation }: MainScreenProps): JSX.Element => ( onPress={() => navigation.navigate('FullscreenModal')} />