diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 57efc48ec8228..6e2125945117e 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2043,7 +2043,7 @@ PODS: - React-RCTText - ReactCommon/turbomodule/core - Yoga - - RNScreens (3.15.0): + - RNScreens (3.17.0): - React-Core - React-RCTImage - Stripe (22.7.1): @@ -3511,7 +3511,7 @@ SPEC CHECKSUMS: RNFlashList: 5116f2de2f543f01bfc30b22d5942d5af84b43df RNGestureHandler: bad495418bcbd3ab47017a38d93d290ebd406f50 RNReanimated: 5c8c17e26787fd8984cd5accdc70fef2ca70aafd - RNScreens: 4a1af06327774490d97342c00aee0c2bafb497b7 + RNScreens: 0df01424e9e0ed7827200d6ed1087ddd06c493f9 Stripe: fb29a476e4866fec4ef22fb76207363dd32795aa stripe-react-native: 5663bf9de94bff6b3d92c16d32784433b5e94cf7 StripeApplePay: 09955cdf3f49b367af2feadd9c5b3bddb35446c0 diff --git a/ios/vendored/unversioned/react-native-screens/RNScreens.podspec.json b/ios/vendored/unversioned/react-native-screens/RNScreens.podspec.json index 6bc8166758c43..77188dae27cfd 100644 --- a/ios/vendored/unversioned/react-native-screens/RNScreens.podspec.json +++ b/ios/vendored/unversioned/react-native-screens/RNScreens.podspec.json @@ -1,6 +1,6 @@ { "name": "RNScreens", - "version": "3.15.0", + "version": "3.17.0", "summary": "Native navigation primitives for your React Native app.", "description": "RNScreens - first incomplete navigation solution for your React Native app", "homepage": "https://github.com/software-mansion/react-native-screens", @@ -14,7 +14,7 @@ }, "source": { "git": "https://github.com/software-mansion/react-native-screens.git", - "tag": "3.15.0" + "tag": "3.17.0" }, "source_files": "ios/**/*.{h,m,mm}", "requires_arc": true, diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.mm index dff0b2fd9e437..e3fedbb24d927 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.mm @@ -4,11 +4,11 @@ #ifdef RN_FABRIC_ENABLED #import +#import #import #import #import #import -#import "RCTFabricComponentsPlugins.h" #else #import #endif // RN_FABRIC_ENABLED diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.h b/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.h index 79a012592c758..a2195b531f4c5 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.h +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.h @@ -103,6 +103,7 @@ NS_ASSUME_NONNULL_BEGIN #endif - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward; +- (BOOL)isModal; @end diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.mm index 066ba3ac81e51..337b32512790f 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.mm @@ -6,13 +6,13 @@ #ifdef RN_FABRIC_ENABLED #import +#import #import #import #import #import #import #import -#import "RCTFabricComponentsPlugins.h" #import "RNSConvert.h" #import "RNSScreenViewEvent.h" #else @@ -508,6 +508,11 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio } } +- (BOOL)isModal +{ + return self.stackPresentation != RNSScreenStackPresentationPush; +} + #pragma mark - Fabric specific #ifdef RN_FABRIC_ENABLED @@ -545,6 +550,17 @@ - (void)prepareForRecycle _dismissed = NO; _state.reset(); _touchHandler = nil; + + // We set this prop to default value here to workaround view-recycling. + // Let's assume the view has had _stackPresentation == set + // before below line was executed. Then, when instantiated again (with the same modal presentation) + // updateProps:oldProps: method would be called and setter for stack presentation would not be called. + // This is crucial as in that setter we register `self.controller` as a delegate + // (UIAdaptivePresentationControllerDelegate) to presentation controller and this leads to buggy modal behaviour as we + // rely on UIAdaptivePresentationControllerDelegate callbacks. Restoring the default value and then comparing against + // it in updateProps:oldProps: allows for setter to be called, however if there was some additional logic to execute + // when stackPresentation is set to "push" the setter would not be triggered. + _stackPresentation = RNSScreenStackPresentationPush; } - (void)updateProps:(facebook::react::Props::Shared const &)props @@ -598,9 +614,12 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props } #endif - if (newScreenProps.stackPresentation != oldScreenProps.stackPresentation) { - [self - setStackPresentation:[RNSConvert RNSScreenStackPresentationFromCppEquivalent:newScreenProps.stackPresentation]]; + // Notice that we compare against _stackPresentation, not oldScreenProps.stackPresentation. + // See comment in prepareForRecycle method for explanation. + RNSScreenStackPresentation newStackPresentation = + [RNSConvert RNSScreenStackPresentationFromCppEquivalent:newScreenProps.stackPresentation]; + if (newStackPresentation != _stackPresentation) { + [self setStackPresentation:newStackPresentation]; } if (newScreenProps.stackAnimation != oldScreenProps.stackAnimation) { @@ -739,7 +758,8 @@ - (void)viewWillAppear:(BOOL)animated - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; - if (!self.transitionCoordinator.isInteractive) { + // self.navigationController might be null when we are dismissing a modal + if (!self.transitionCoordinator.isInteractive && self.navigationController != nil) { // user might have long pressed ios 14 back button item, // so he can go back more than one screen and we need to dismiss more screens in JS stack then. // We check it by calculating the difference between the index of currently displayed screen diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.mm index fe83a272545a8..baea98c1a1f77 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.mm @@ -3,9 +3,9 @@ #ifdef RN_FABRIC_ENABLED #import +#import #import #import -#import "RCTFabricComponentsPlugins.h" #endif @implementation RNScreensViewController diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenNavigationContainer.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenNavigationContainer.mm index c328064961554..b32546c9bb38f 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenNavigationContainer.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenNavigationContainer.mm @@ -3,9 +3,9 @@ #import "RNSScreenContainer.h" #ifdef RN_FABRIC_ENABLED +#import #import #import -#import "RCTFabricComponentsPlugins.h" #endif @implementation RNScreensContainerNavigationController diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.mm index 81322b1e4aae1..8744a64f6a811 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.mm @@ -7,7 +7,7 @@ #import #import -#import "RCTFabricComponentsPlugins.h" +#import #else #import @@ -823,7 +823,7 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceive RNSScreenView *topScreen = _reactSubviews.lastObject; if (![topScreen isKindOfClass:[RNSScreenView class]] || !topScreen.gestureEnabled || - _controller.viewControllers.count < 2) { + _controller.viewControllers.count < 2 || [topScreen isModal]) { return NO; } @@ -969,7 +969,7 @@ - (void)takeSnapshot - (void)mountingTransactionWillMount:(facebook::react::MountingTransaction const &)transaction withSurfaceTelemetry:(facebook::react::SurfaceTelemetry const &)surfaceTelemetry { - for (auto mutation : transaction.getMutations()) { + for (auto &mutation : transaction.getMutations()) { if (mutation.type == facebook::react::ShadowViewMutation::Type::Remove && mutation.parentShadowView.componentName != nil && strcmp(mutation.parentShadowView.componentName, "RNSScreenStack") == 0) { diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.mm index 01f1480675d5f..7c5fa1b01a1c9 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.mm @@ -1,11 +1,11 @@ #ifdef RN_FABRIC_ENABLED #import +#import #import #import #import #import #import -#import "RCTFabricComponentsPlugins.h" #else #import #import @@ -118,7 +118,7 @@ - (void)updateViewControllerIfNeeded } // we want updates sent to the VC below modal too since it is also visible - BOOL isPresentingVC = vc.presentedViewController == nextVC; + BOOL isPresentingVC = nextVC != nil && vc.presentedViewController == nextVC; BOOL isInFullScreenModal = nav == nil && _screenView.stackPresentation == RNSScreenStackPresentationFullScreenModal; // if nav is nil, it means we can be in a fullScreen modal, so there is no nextVC, but we still want to update @@ -459,7 +459,6 @@ + (void)updateViewController:(UIViewController *)vc return; } - navitem.title = config.title; #if !TARGET_OS_TV if (config.backTitle != nil || config.backTitleFontFamily || config.backTitleFontSize || config.disableBackButtonMenu) { @@ -580,13 +579,17 @@ + (void)updateViewController:(UIViewController *)vc } case RNSScreenStackHeaderSubviewTypeBackButton: { #ifdef RN_FABRIC_ENABLED - RCTLogWarn(@"Back button subivew is not yet Fabric compatible in react-native-screens"); + RCTLogWarn(@"Back button subview is not yet Fabric compatible in react-native-screens"); #endif break; } } } + // This assignment should be done after `navitem.titleView = ...` assignment (iOS 16.0 bug). + // See: https://github.com/software-mansion/react-native-screens/issues/1570 (comments) + navitem.title = config.title; + if (animated && vc.transitionCoordinator != nil && vc.transitionCoordinator.presentationStyle == UIModalPresentationNone && !wasHidden) { // when there is an ongoing transition we may need to update navbar setting in animation block diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.mm index 5d0ead1f483a6..70a430b04062d 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.mm @@ -7,7 +7,7 @@ #import #import -#import "RCTFabricComponentsPlugins.h" +#import #endif @implementation RNSScreenStackHeaderSubview diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.mm index 12b7dc2c272d1..ebd322406d628 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.mm @@ -8,11 +8,11 @@ #ifdef RN_FABRIC_ENABLED #import +#import #import #import #import #import -#import "RCTFabricComponentsPlugins.h" #import "RNSConvert.h" #endif