From 6c79b93a0a201a322ca56969edc83b91b5ba6c29 Mon Sep 17 00:00:00 2001 From: Hirbod <504909+hirbod@users.noreply.github.com> Date: Sat, 8 Jun 2024 12:16:34 +0200 Subject: [PATCH 01/13] fix: dismiss foreign modals correctly on reload --- ios/RNSScreenStack.mm | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 14d1872b50..db0e31fd11 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -1191,15 +1191,24 @@ - (void)prepareForRecycle #else #pragma mark - Paper specific -- (void)invalidate -{ +- (void)invalidate { _invalidated = YES; - for (UIViewController *controller in _presentedModals) { - [controller dismissViewControllerAnimated:NO completion:nil]; + [self dismissAllPresentedViewControllersFrom:_controller completion:^{ + // Ensure presented modals are removed and the controller is detached from its parent + [self->_presentedModals removeAllObjects]; + [self->_controller willMoveToParentViewController:nil]; + [self->_controller removeFromParentViewController]; + }]; +} + +- (void)dismissAllPresentedViewControllersFrom:(UIViewController *)viewController completion:(void (^)(void))completion { + if (viewController.presentedViewController) { + [viewController.presentedViewController dismissViewControllerAnimated:NO completion:^{ + [self dismissAllPresentedViewControllersFrom:viewController completion:completion]; + }]; + } else { + completion(); } - [_presentedModals removeAllObjects]; - [_controller willMoveToParentViewController:nil]; - [_controller removeFromParentViewController]; } #endif // RCT_NEW_ARCH_ENABLED From 01a9932ff1a88176d8820418a825f9f19726dc59 Mon Sep 17 00:00:00 2001 From: Hirbod <504909+hirbod@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:18:53 +0200 Subject: [PATCH 02/13] Update RNSScreenStack.mm --- ios/RNSScreenStack.mm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index db0e31fd11..8cc10f7881 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -686,7 +686,9 @@ - (void)dismissOnReload #ifdef RCT_NEW_ARCH_ENABLED #else dispatch_async(dispatch_get_main_queue(), ^{ - [self invalidate]; + [self dismissAllPresentedViewControllersFrom:self->_controller completion:^{ + [self invalidate]; + }]; }); #endif // RCT_NEW_ARCH_ENABLED } @@ -1193,18 +1195,16 @@ - (void)prepareForRecycle - (void)invalidate { _invalidated = YES; - [self dismissAllPresentedViewControllersFrom:_controller completion:^{ - // Ensure presented modals are removed and the controller is detached from its parent - [self->_presentedModals removeAllObjects]; - [self->_controller willMoveToParentViewController:nil]; - [self->_controller removeFromParentViewController]; - }]; + [_presentedModals removeAllObjects]; + [_controller willMoveToParentViewController:nil]; + [_controller removeFromParentViewController]; } - (void)dismissAllPresentedViewControllersFrom:(UIViewController *)viewController completion:(void (^)(void))completion { if (viewController.presentedViewController) { [viewController.presentedViewController dismissViewControllerAnimated:NO completion:^{ [self dismissAllPresentedViewControllersFrom:viewController completion:completion]; + [self invalidate]; }]; } else { completion(); From c9e31d8519c7dad39ccffc0bae26d93057842f2c Mon Sep 17 00:00:00 2001 From: Hirbod <504909+hirbod@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:35:26 +0200 Subject: [PATCH 03/13] revert: Update RNSScreenStack.mm --- ios/RNSScreenStack.mm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 8cc10f7881..db0e31fd11 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -686,9 +686,7 @@ - (void)dismissOnReload #ifdef RCT_NEW_ARCH_ENABLED #else dispatch_async(dispatch_get_main_queue(), ^{ - [self dismissAllPresentedViewControllersFrom:self->_controller completion:^{ - [self invalidate]; - }]; + [self invalidate]; }); #endif // RCT_NEW_ARCH_ENABLED } @@ -1195,16 +1193,18 @@ - (void)prepareForRecycle - (void)invalidate { _invalidated = YES; - [_presentedModals removeAllObjects]; - [_controller willMoveToParentViewController:nil]; - [_controller removeFromParentViewController]; + [self dismissAllPresentedViewControllersFrom:_controller completion:^{ + // Ensure presented modals are removed and the controller is detached from its parent + [self->_presentedModals removeAllObjects]; + [self->_controller willMoveToParentViewController:nil]; + [self->_controller removeFromParentViewController]; + }]; } - (void)dismissAllPresentedViewControllersFrom:(UIViewController *)viewController completion:(void (^)(void))completion { if (viewController.presentedViewController) { [viewController.presentedViewController dismissViewControllerAnimated:NO completion:^{ [self dismissAllPresentedViewControllersFrom:viewController completion:completion]; - [self invalidate]; }]; } else { completion(); From 8a023887db916024dcdef446882568ca2b01f17f Mon Sep 17 00:00:00 2001 From: Hirbod <504909+hirbod@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:52:50 +0200 Subject: [PATCH 04/13] fix: hard detach This change aligns more with the current behaviour --- ios/RNSScreenStack.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index db0e31fd11..7172cae5a0 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -1203,7 +1203,7 @@ - (void)invalidate { - (void)dismissAllPresentedViewControllersFrom:(UIViewController *)viewController completion:(void (^)(void))completion { if (viewController.presentedViewController) { - [viewController.presentedViewController dismissViewControllerAnimated:NO completion:^{ + [viewController.presentedViewController dismissViewControllerAnimated:YES completion:^{ [self dismissAllPresentedViewControllersFrom:viewController completion:completion]; }]; } else { From e238dda4ffcf9f9f47ea43607dce9563d0a7709e Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 27 Jun 2024 12:17:36 +0200 Subject: [PATCH 05/13] Format code --- ios/RNSScreenStack.mm | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 7172cae5a0..72df8d7a68 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -1191,21 +1191,27 @@ - (void)prepareForRecycle #else #pragma mark - Paper specific -- (void)invalidate { +- (void)invalidate +{ _invalidated = YES; - [self dismissAllPresentedViewControllersFrom:_controller completion:^{ - // Ensure presented modals are removed and the controller is detached from its parent - [self->_presentedModals removeAllObjects]; - [self->_controller willMoveToParentViewController:nil]; - [self->_controller removeFromParentViewController]; - }]; + [self dismissAllPresentedViewControllersFrom:_controller + completion:^{ + // Ensure presented modals are removed and the controller is detached from its + // parent + [self->_presentedModals removeAllObjects]; + [self->_controller willMoveToParentViewController:nil]; + [self->_controller removeFromParentViewController]; + }]; } -- (void)dismissAllPresentedViewControllersFrom:(UIViewController *)viewController completion:(void (^)(void))completion { +- (void)dismissAllPresentedViewControllersFrom:(UIViewController *)viewController completion:(void (^)(void))completion +{ if (viewController.presentedViewController) { - [viewController.presentedViewController dismissViewControllerAnimated:YES completion:^{ - [self dismissAllPresentedViewControllersFrom:viewController completion:completion]; - }]; + [viewController.presentedViewController + dismissViewControllerAnimated:YES + completion:^{ + [self dismissAllPresentedViewControllersFrom:viewController completion:completion]; + }]; } else { completion(); } From 2138a886db50987738bd52cf8cb64d76750170b4 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 26 Sep 2024 13:58:57 +0200 Subject: [PATCH 06/13] Add repro with old solution --- apps/App.tsx | 8 +- apps/src/tests/Test2175.tsx | 131 ++++++++++++++++++++ apps/src/tests/index.ts | 232 ++++++++++++++++++------------------ ios/RNSScreenStack.mm | 32 +++-- 4 files changed, 276 insertions(+), 127 deletions(-) create mode 100644 apps/src/tests/Test2175.tsx diff --git a/apps/App.tsx b/apps/App.tsx index 23a9af9c45..e845fd9f02 100644 --- a/apps/App.tsx +++ b/apps/App.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { enableFreeze } from 'react-native-screens'; -import Example from './Example'; -// import * as Test from './src/tests'; +// import Example from './Example'; +import * as Test from './src/tests'; enableFreeze(true); export default function App() { - return ; - // return ; + // return ; + return ; } diff --git a/apps/src/tests/Test2175.tsx b/apps/src/tests/Test2175.tsx new file mode 100644 index 0000000000..9155ee5b15 --- /dev/null +++ b/apps/src/tests/Test2175.tsx @@ -0,0 +1,131 @@ +import React from 'react'; +import { Button, Modal, SafeAreaView, Text, View } from 'react-native'; + +import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { NavigationContainer } from '@react-navigation/native'; +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; + +const Stack = createNativeStackNavigator(); +const Tabs = createBottomTabNavigator(); + + +function TabScreens({ navigation }): React.JSX.Element { + return ( + + + + + ); +} + +function TabHomeScreen({ navigation }): React.JSX.Element { + return ( + + Where do you where do you go, my lovely, oh oh oh oh +