Enable Multiple Sheet Presentation in React Native (#46316)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46316

This pull request introduces enhancements to the view controller presentation logic in React Native, allowing for multiple sheets to be presented on top of each other. The current implementation restricts the presentation to a single view at a time, which limits the flexibility needed in complex applications.

The proposed changes modify the presentation behavior to always utilize the top-most view controller for presentations. This adjustment ensures that multiple sheets can be managed more effectively, without disrupting the existing application flow.

Key changes include:
Modification of the presentation logic to reference the top-most view controller.
Utilization of a recursive method to determine the top-most controller.

The changes have been thoroughly tested with both old and new interfaces and have shown to work seamlessly across different scenarios

Changelog: [Internal] Allow multiple sheets to be presented on top of each other

Reviewed By: cipolleschi

Differential Revision: D62143463

fbshipit-source-id: 53667cf1a75e4514156780574bf604aee6b3fefc
This commit is contained in:
Mohamed Alsadek
2024-09-04 02:54:32 -07:00
committed by Facebook GitHub Bot
parent 0a1ba02273
commit dea5a6ca60
@@ -134,7 +134,9 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
completion:(void (^)(void))completion
{
UIViewController *controller = [self reactViewController];
[controller presentViewController:modalViewController animated:animated completion:completion];
[[self _topMostViewControllerFrom:controller] presentViewController:modalViewController
animated:animated
completion:completion];
}
- (void)dismissViewController:(UIViewController *)modalViewController
@@ -274,6 +276,26 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
[childComponentView removeFromSuperview];
}
#pragma mark - Private
- (UIViewController *)_topMostViewControllerFrom:(UIViewController *)rootViewController
{
UIViewController *topController = rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
if ([topController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)topController;
topController = navigationController.visibleViewController;
return [self _topMostViewControllerFrom:topController];
} else if ([topController isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabBarController = (UITabBarController *)topController;
topController = tabBarController.selectedViewController;
return [self _topMostViewControllerFrom:topController];
}
return topController;
}
@end
#ifdef __cplusplus