react-native-screens 5.0.0-alpha.3 → 5.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/android/build.gradle +1 -0
- package/android/consumer-rules.pro +3 -0
- package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledHeaderConfigViewGroup.kt +2 -0
- package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledHeaderSubviewViewGroup.kt +2 -0
- package/android/src/fabric/java/com/swmansion/rnscreens/legacy/FabricEnabledViewGroup.kt +18 -3
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +7 -3
- package/android/src/main/java/com/swmansion/rnscreens/common/colorscheme/ColorSchemeCoordinator.kt +11 -1
- package/android/src/main/java/com/swmansion/rnscreens/common/container/Container.kt +9 -0
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetAppearanceCoordinator.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetBehaviorController.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetDimensionsCoordinator.kt +6 -6
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetKeyboardCoordinator.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/coordinator/FormSheetNativeDismissCoordinator.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetAvailableHeightProvider.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetContainer.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetDialog.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native/core → core/modals/formsheet/dialog}/FormSheetDialogManager.kt +26 -8
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetContentSizeChangeDelegate.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetContentSizeChangeProvider.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/interfaces/FormSheetDialogEventEmitter.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/model/FormSheetConfig.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/model/FormSheetDetents.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetAnimatorFactory.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetDimmingManager.kt +6 -18
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetDismissalOrigin.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetPresentation.kt +10 -10
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetPresentationManager.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetPresentationState.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/native → core/modals/formsheet}/presentation/FormSheetStackRegistry.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/ext/FragmentManagerExt.kt +6 -0
- package/android/src/main/java/com/swmansion/rnscreens/helpers/FragmentManagerHelper.kt +0 -3
- package/android/src/main/java/com/swmansion/rnscreens/helpers/NoTintDrawable.kt +31 -0
- package/android/src/main/java/com/swmansion/rnscreens/helpers/ViewFinder.kt +0 -17
- package/android/src/main/java/com/swmansion/rnscreens/legacy/Screen.kt +29 -2
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenContainer.kt +35 -3
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStack.kt +13 -0
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackHeaderConfig.kt +7 -1
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackHeaderSubviewManager.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStackViewManager.kt +6 -0
- package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/DimmingView.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/legacy/stack/views/ScreensCoordinatorLayout.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/contentwrapper/FormSheetContentWrapper.kt +3 -3
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/contentwrapper/FormSheetContentWrapperViewManager.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDetentChangedEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDidAppearEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDidDisappearEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetDismissEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetNativeDismissEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetNativeDismissPreventedEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetSyncFlushEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetWillAppearEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/event/FormSheetWillDisappearEvent.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetContentView.kt +3 -3
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHost.kt +5 -3
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHostEventEmitter.kt +11 -11
- package/android/src/main/java/com/swmansion/rnscreens/{modals/formsheet/react → react/modals/formsheet}/host/FormSheetHostViewManager.kt +10 -10
- package/android/src/main/java/com/swmansion/rnscreens/safearea/OnInterfaceInsetsChangeListener.kt +15 -0
- package/android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaProvider.kt +8 -8
- package/android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaView.kt +3 -2
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderApplicator.kt +0 -52
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderCoordinatorLayout.kt +112 -59
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderAppBarLayout.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderToolbar.kt +74 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfig.kt +4 -73
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationObserver.kt +5 -2
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationProviding.kt +0 -6
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderInvalidationFlags.kt +3 -7
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/FragmentOperation.kt +1 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/FragmentOperationExecutor.kt +2 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainer.kt +57 -19
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainerDelegate.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainerUpdateCoordinator.kt +5 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHost.kt +14 -5
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackUpdateBatchStateProviding.kt +10 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/PreventNativeDismissCallback.kt +2 -2
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragment.kt +33 -12
- package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceApplicator.kt +106 -10
- package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceCoordinator.kt +44 -3
- package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceModel.kt +3 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/CustomBottomNavigationView.kt +21 -1
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainer.kt +28 -13
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainerDelegate.kt +11 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHost.kt +12 -2
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreen.kt +41 -17
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenDelegate.kt +6 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenIcon.kt +82 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenIconTinting.kt +17 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenViewManager.kt +26 -19
- package/android/src/main/java/com/swmansion/rnscreens/utils/DimensionUtils.kt +14 -7
- package/android/src/main/java/com/swmansion/rnscreens/utils/RNSLog.kt +22 -6
- package/ios/RNSEnums.h +14 -1
- package/ios/helpers/image/RNSImageLoadingHelper.h +7 -0
- package/ios/helpers/image/RNSImageLoadingHelper.mm +9 -0
- package/ios/legacy/RNSBarButtonItem.mm +15 -0
- package/ios/legacy/RNSConvert.h +6 -0
- package/ios/legacy/RNSConvert.mm +17 -0
- package/ios/legacy/RNSNavigationBar.h +31 -0
- package/ios/legacy/RNSNavigationBar.mm +15 -0
- package/ios/legacy/RNSScreen.mm +122 -12
- package/ios/legacy/RNSScreenContentWrapper.mm +4 -1
- package/ios/legacy/RNSScreenStack.mm +202 -15
- package/ios/legacy/RNSScreenStackHeaderConfig.h +30 -0
- package/ios/legacy/RNSScreenStackHeaderConfig.mm +70 -17
- package/ios/legacy/RNSScreenStackHeaderSubview.mm +33 -0
- package/ios/safe-area/RNSSafeAreaViewComponentView.mm +1 -12
- package/ios/stack/conversion/RNSConversions-Stack.h +30 -0
- package/ios/stack/conversion/RNSConversions-Stack.mm +79 -0
- package/ios/stack/header/RNSHeaderItemVisibilityPriority.h +9 -0
- package/ios/stack/header/RNSStackHeaderConfigComponentView.h +4 -0
- package/ios/stack/header/RNSStackHeaderConfigComponentView.mm +40 -6
- package/ios/stack/header/RNSStackHeaderConfigDataProviding.h +5 -0
- package/ios/stack/header/RNSStackHeaderContentFactory.mm +3 -0
- package/ios/stack/header/RNSStackHeaderItemComponentView.h +9 -2
- package/ios/stack/header/RNSStackHeaderItemComponentView.mm +57 -3
- package/ios/stack/header/RNSStackHeaderItemDataProviding.h +5 -0
- package/ios/stack/header/RNSStackHeaderMenuCoordinator.h +13 -0
- package/ios/stack/header/RNSStackHeaderMenuCoordinator.mm +24 -0
- package/ios/stack/header/RNSStackHeaderMenuFinder.h +8 -1
- package/ios/stack/header/RNSStackHeaderMenuFinder.mm +26 -9
- package/ios/stack/screen/RNSStackScreenComponentView.h +2 -1
- package/ios/stack/screen/RNSStackScreenComponentView.mm +23 -0
- package/ios/stack/screen/RNSStackScreenHeaderCoordinator.mm +81 -8
- package/ios/tabs/RNSTabBarAppearanceCoordinator.mm +79 -16
- package/ios/tabs/RNSTabBarItemCoordinator.h +16 -0
- package/ios/tabs/RNSTabBarItemCoordinator.mm +143 -0
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryWrapperView.h +24 -0
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryWrapperView.mm +22 -0
- package/ios/tabs/conversion/RNSConversions-Tabs.h +22 -0
- package/ios/tabs/conversion/RNSConversions-Tabs.mm +97 -3
- package/ios/tabs/host/RNSTabBarController.h +16 -0
- package/ios/tabs/host/RNSTabBarController.mm +516 -107
- package/ios/tabs/host/RNSTabsHostComponentView.h +2 -0
- package/ios/tabs/host/RNSTabsHostComponentView.mm +32 -2
- package/ios/tabs/screen/RNSTabsScreenComponentView.h +21 -0
- package/ios/tabs/screen/RNSTabsScreenComponentView.mm +54 -69
- package/ios/tabs/screen/RNSTabsScreenViewController.mm +1 -0
- package/ios/utils/RNSDefines.h +12 -7
- package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js +3 -2
- package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js.map +1 -1
- package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js +8 -3
- package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
- package/lib/commonjs/components/stack/header/StackHeaderConfig.js +17 -0
- package/lib/commonjs/components/stack/header/StackHeaderConfig.js.map +1 -0
- package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js +4 -1
- package/lib/commonjs/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
- package/lib/commonjs/components/stack/host/StackHost.js +8 -1
- package/lib/commonjs/components/stack/host/StackHost.js.map +1 -1
- package/lib/commonjs/components/stack/host/StackHost.web.js +0 -2
- package/lib/commonjs/components/stack/host/StackHost.web.js.map +1 -1
- package/lib/commonjs/components/stack/index.js.map +1 -1
- package/lib/commonjs/components/tabs/host/TabsHost.ios.js +2 -0
- package/lib/commonjs/components/tabs/host/TabsHost.ios.js.map +1 -1
- package/lib/commonjs/components/tabs/host/{TabsHost.web.js → TabsHost.js} +1 -1
- package/lib/commonjs/components/tabs/host/TabsHost.js.map +1 -0
- package/lib/commonjs/components/tabs/index.js.map +1 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.android.js +3 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.android.js.map +1 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.ios.js +10 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.ios.js.map +1 -1
- package/lib/commonjs/components/tabs/screen/{TabsScreen.web.js → TabsScreen.js} +1 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.js.map +1 -0
- package/lib/commonjs/components/{stack/header/StackHeaderConfig.d.js → tabs/screen/TabsScreenIcon.types.js} +1 -1
- package/lib/commonjs/components/{stack/header/StackHeaderConfig.d.js.map → tabs/screen/TabsScreenIcon.types.js.map} +1 -1
- package/lib/commonjs/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js +1 -1
- package/lib/commonjs/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/legacy/components/ScreenStackItem.js +31 -11
- package/lib/commonjs/legacy/components/ScreenStackItem.js.map +1 -1
- package/lib/module/components/stack/header/StackHeaderConfig.android.js +4 -3
- package/lib/module/components/stack/header/StackHeaderConfig.android.js.map +1 -1
- package/lib/module/components/stack/header/StackHeaderConfig.ios.js +9 -4
- package/lib/module/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
- package/lib/module/components/stack/header/StackHeaderConfig.js +10 -0
- package/lib/module/components/stack/header/StackHeaderConfig.js.map +1 -0
- package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js +4 -1
- package/lib/module/components/stack/header/ios/StackHeaderItem.ios.js.map +1 -1
- package/lib/module/components/stack/host/StackHost.js +9 -2
- package/lib/module/components/stack/host/StackHost.js.map +1 -1
- package/lib/module/components/stack/host/StackHost.web.js +0 -3
- package/lib/module/components/stack/host/StackHost.web.js.map +1 -1
- package/lib/module/components/stack/index.js.map +1 -1
- package/lib/module/components/tabs/host/TabsHost.ios.js +2 -0
- package/lib/module/components/tabs/host/TabsHost.ios.js.map +1 -1
- package/{src/components/tabs/host/TabsHost.web.tsx → lib/module/components/tabs/host/TabsHost.js} +1 -2
- package/lib/module/components/tabs/host/TabsHost.js.map +1 -0
- package/lib/module/components/tabs/index.js.map +1 -1
- package/lib/module/components/tabs/screen/TabsScreen.android.js +3 -1
- package/lib/module/components/tabs/screen/TabsScreen.android.js.map +1 -1
- package/lib/module/components/tabs/screen/TabsScreen.ios.js +10 -1
- package/lib/module/components/tabs/screen/TabsScreen.ios.js.map +1 -1
- package/{src/components/tabs/screen/TabsScreen.web.tsx → lib/module/components/tabs/screen/TabsScreen.js} +1 -2
- package/lib/module/components/tabs/screen/TabsScreen.js.map +1 -0
- package/lib/module/components/tabs/screen/TabsScreenIcon.types.js +2 -0
- package/lib/module/components/{stack/header/StackHeaderConfig.d.js.map → tabs/screen/TabsScreenIcon.types.js.map} +1 -1
- package/lib/module/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.js.map +1 -1
- package/lib/module/fabric/legacy/ScreenStackNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsScreenAndroidNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js +1 -1
- package/lib/module/fabric/tabs/TabsScreenIOSNativeComponent.js.map +1 -1
- package/lib/module/legacy/components/ScreenStackItem.js +31 -11
- package/lib/module/legacy/components/ScreenStackItem.js.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts +6 -3
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts +4 -3
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.d.ts +8 -0
- package/lib/typescript/components/stack/header/StackHeaderConfig.d.ts.map +1 -0
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts +6 -3
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts +137 -2
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts +2 -0
- package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts +5 -0
- package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.types.d.ts +24 -1
- package/lib/typescript/components/stack/host/StackHost.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.web.d.ts +1 -3
- package/lib/typescript/components/stack/host/StackHost.web.d.ts.map +1 -1
- package/lib/typescript/components/stack/index.d.ts +4 -3
- package/lib/typescript/components/stack/index.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.d.ts +5 -0
- package/lib/typescript/components/tabs/host/TabsHost.d.ts.map +1 -0
- package/lib/typescript/components/tabs/host/TabsHost.ios.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts +56 -0
- package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/tabs/index.d.ts +4 -6
- package/lib/typescript/components/tabs/index.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.android.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.android.types.d.ts +42 -7
- package/lib/typescript/components/tabs/screen/TabsScreen.android.types.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.d.ts +5 -0
- package/lib/typescript/components/tabs/screen/TabsScreen.d.ts.map +1 -0
- package/lib/typescript/components/tabs/screen/TabsScreen.ios.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.ios.types.d.ts +78 -13
- package/lib/typescript/components/tabs/screen/TabsScreen.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/tabs/screen/TabsScreenIcon.types.d.ts +91 -0
- package/lib/typescript/components/tabs/screen/TabsScreenIcon.types.d.ts.map +1 -0
- package/lib/typescript/components/tabs/screen/index.d.ts +1 -0
- package/lib/typescript/components/tabs/screen/index.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts +2 -0
- package/lib/typescript/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts +1 -0
- package/lib/typescript/fabric/legacy/ScreenStackNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts +4 -0
- package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts +6 -0
- package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts +3 -0
- package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts +6 -0
- package/lib/typescript/fabric/tabs/TabsScreenAndroidNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts +10 -1
- package/lib/typescript/fabric/tabs/TabsScreenIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/legacy/components/ScreenStackItem.d.ts +25 -0
- package/lib/typescript/legacy/components/ScreenStackItem.d.ts.map +1 -1
- package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts +4 -0
- package/lib/typescript/legacy/components/helpers/prepareHeaderBarButtonItems.d.ts.map +1 -1
- package/lib/typescript/legacy/types.d.ts +30 -0
- package/lib/typescript/legacy/types.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/components/stack/header/StackHeaderConfig.android.tsx +6 -20
- package/src/components/stack/header/StackHeaderConfig.android.types.ts +4 -3
- package/src/components/stack/header/StackHeaderConfig.ios.tsx +10 -16
- package/src/components/stack/header/StackHeaderConfig.ios.types.ts +148 -2
- package/src/components/stack/header/StackHeaderConfig.tsx +12 -0
- package/src/components/stack/header/StackHeaderConfig.types.ts +2 -0
- package/src/components/stack/header/ios/StackHeaderItem.ios.tsx +9 -1
- package/src/components/stack/header/ios/StackHeaderItem.ios.types.ts +5 -0
- package/src/components/stack/host/StackHost.tsx +10 -3
- package/src/components/stack/host/StackHost.types.ts +25 -1
- package/src/components/stack/host/StackHost.web.tsx +1 -4
- package/src/components/stack/index.ts +9 -1
- package/src/components/tabs/host/TabsHost.ios.tsx +2 -0
- package/src/components/tabs/host/TabsHost.ios.types.ts +60 -0
- package/src/components/tabs/host/TabsHost.tsx +7 -0
- package/src/components/tabs/index.ts +9 -0
- package/src/components/tabs/screen/TabsScreen.android.tsx +8 -3
- package/src/components/tabs/screen/TabsScreen.android.types.ts +42 -7
- package/src/components/tabs/screen/TabsScreen.ios.tsx +22 -5
- package/src/components/tabs/screen/TabsScreen.ios.types.ts +79 -17
- package/src/components/tabs/screen/TabsScreen.tsx +7 -0
- package/src/components/tabs/screen/TabsScreenIcon.types.ts +117 -0
- package/src/components/tabs/screen/index.ts +1 -0
- package/src/fabric/legacy/ScreenStackHeaderSubviewNativeComponent.ts +6 -0
- package/src/fabric/legacy/ScreenStackNativeComponent.ts +2 -0
- package/src/fabric/stack/StackHeaderConfigIOSNativeComponent.ts +11 -0
- package/src/fabric/stack/StackHeaderItemIOSNativeComponent.ts +11 -0
- package/src/fabric/tabs/TabsHostIOSNativeComponent.ts +7 -0
- package/src/fabric/tabs/TabsScreenAndroidNativeComponent.ts +9 -0
- package/src/fabric/tabs/TabsScreenIOSNativeComponent.ts +20 -2
- package/src/legacy/components/ScreenStackItem.tsx +59 -12
- package/src/legacy/types.ts +31 -0
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenModalFragment.kt +0 -281
- package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/BottomSheetDialogRootView.kt +0 -104
- package/android/src/main/java/com/swmansion/rnscreens/legacy/bottomsheet/BottomSheetDialogScreen.kt +0 -26
- package/lib/commonjs/components/stack/header/StackHeaderConfig.web.js +0 -10
- package/lib/commonjs/components/stack/header/StackHeaderConfig.web.js.map +0 -1
- package/lib/commonjs/components/tabs/host/TabsHost.d.js +0 -2
- package/lib/commonjs/components/tabs/host/TabsHost.d.js.map +0 -1
- package/lib/commonjs/components/tabs/host/TabsHost.web.js.map +0 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.d.js +0 -2
- package/lib/commonjs/components/tabs/screen/TabsScreen.d.js.map +0 -1
- package/lib/commonjs/components/tabs/screen/TabsScreen.web.js.map +0 -1
- package/lib/module/components/stack/header/StackHeaderConfig.d.js +0 -2
- package/lib/module/components/stack/header/StackHeaderConfig.web.js +0 -4
- package/lib/module/components/stack/header/StackHeaderConfig.web.js.map +0 -1
- package/lib/module/components/tabs/host/TabsHost.d.js +0 -2
- package/lib/module/components/tabs/host/TabsHost.d.js.map +0 -1
- package/lib/module/components/tabs/host/TabsHost.web.js +0 -4
- package/lib/module/components/tabs/host/TabsHost.web.js.map +0 -1
- package/lib/module/components/tabs/screen/TabsScreen.d.js +0 -2
- package/lib/module/components/tabs/screen/TabsScreen.d.js.map +0 -1
- package/lib/module/components/tabs/screen/TabsScreen.web.js +0 -4
- package/lib/module/components/tabs/screen/TabsScreen.web.js.map +0 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts +0 -7
- package/lib/typescript/components/stack/header/StackHeaderConfig.web.d.ts.map +0 -1
- package/lib/typescript/components/tabs/host/TabsHost.web.d.ts +0 -7
- package/lib/typescript/components/tabs/host/TabsHost.web.d.ts.map +0 -1
- package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts +0 -7
- package/lib/typescript/components/tabs/screen/TabsScreen.web.d.ts.map +0 -1
- package/src/components/stack/header/StackHeaderConfig.d.ts +0 -22
- package/src/components/stack/header/StackHeaderConfig.web.tsx +0 -5
- package/src/components/tabs/host/TabsHost.d.ts +0 -12
- package/src/components/tabs/screen/TabsScreen.d.ts +0 -12
|
@@ -59,6 +59,15 @@
|
|
|
59
59
|
}];
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
+ (nullable UIImage *)symbolImageNamed:(nonnull NSString *)name
|
|
63
|
+
{
|
|
64
|
+
UIImage *image = [UIImage systemImageNamed:name];
|
|
65
|
+
if (image == nil) {
|
|
66
|
+
image = [UIImage imageNamed:name];
|
|
67
|
+
}
|
|
68
|
+
return image;
|
|
69
|
+
}
|
|
70
|
+
|
|
62
71
|
+ (nullable UIImage *)handleRenderingModeForImage:(nullable UIImage *)image isTemplate:(BOOL)isTemplate
|
|
63
72
|
{
|
|
64
73
|
if (isTemplate) {
|
|
@@ -89,6 +89,21 @@ static UIMenuOptions RNSMakeUIMenuOptionsFromConfig(NSDictionary *config);
|
|
|
89
89
|
}
|
|
90
90
|
#endif
|
|
91
91
|
|
|
92
|
+
// tvOS and visionOS are excluded on purpose: `visibilityPriority` exists there, but the only
|
|
93
|
+
// supported value is `standard`, which is already the default.
|
|
94
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(27_0) && !TARGET_OS_TV && !TARGET_OS_VISION
|
|
95
|
+
if (@available(iOS 27.0, *)) {
|
|
96
|
+
NSString *visibilityPriority = dict[@"visibilityPriority"];
|
|
97
|
+
if ([visibilityPriority isEqualToString:@"low"]) {
|
|
98
|
+
self.visibilityPriority = UIBarButtonItemVisibilityPriorityLow;
|
|
99
|
+
} else if ([visibilityPriority isEqualToString:@"high"]) {
|
|
100
|
+
self.visibilityPriority = UIBarButtonItemVisibilityPriorityHigh;
|
|
101
|
+
} else if ([visibilityPriority isEqualToString:@"standard"]) {
|
|
102
|
+
self.visibilityPriority = UIBarButtonItemVisibilityPriorityStandard;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(27_0) && !TARGET_OS_TV && !TARGET_OS_VISION
|
|
106
|
+
|
|
92
107
|
NSString *variant = dict[@"variant"];
|
|
93
108
|
if (variant) {
|
|
94
109
|
if ([variant isEqualToString:@"done"]) {
|
package/ios/legacy/RNSConvert.h
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#if defined(__cplusplus)
|
|
5
5
|
#import <react/renderer/components/rnscreens/Props.h>
|
|
6
6
|
#endif // __cplusplus
|
|
7
|
+
#import "RNSDefines.h"
|
|
7
8
|
#import "RNSLegacyEnums.h"
|
|
8
9
|
|
|
9
10
|
#if defined(__cplusplus)
|
|
@@ -31,6 +32,11 @@ namespace react = facebook::react;
|
|
|
31
32
|
+ (RNSScreenStackHeaderSubviewType)RNSScreenStackHeaderSubviewTypeFromCppEquivalent:
|
|
32
33
|
(react::RNSScreenStackHeaderSubviewType)subviewType;
|
|
33
34
|
|
|
35
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(27_0)
|
|
36
|
+
+ (UIBarButtonItemVisibilityPriority)UIBarButtonItemVisibilityPriorityFromCppEquivalent:
|
|
37
|
+
(react::RNSScreenStackHeaderSubviewVisibilityPriority)visibilityPriority API_AVAILABLE(ios(27.0));
|
|
38
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(27_0)
|
|
39
|
+
|
|
34
40
|
+ (RNSScreenReplaceAnimation)RNSScreenReplaceAnimationFromCppEquivalent:
|
|
35
41
|
(react::RNSScreenReplaceAnimation)replaceAnimation;
|
|
36
42
|
|
package/ios/legacy/RNSConvert.mm
CHANGED
|
@@ -118,6 +118,23 @@
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(27_0)
|
|
122
|
+
+ (UIBarButtonItemVisibilityPriority)UIBarButtonItemVisibilityPriorityFromCppEquivalent:
|
|
123
|
+
(react::RNSScreenStackHeaderSubviewVisibilityPriority)visibilityPriority
|
|
124
|
+
{
|
|
125
|
+
switch (visibilityPriority) {
|
|
126
|
+
using enum react::RNSScreenStackHeaderSubviewVisibilityPriority;
|
|
127
|
+
|
|
128
|
+
case Low:
|
|
129
|
+
return UIBarButtonItemVisibilityPriorityLow;
|
|
130
|
+
case High:
|
|
131
|
+
return UIBarButtonItemVisibilityPriorityHigh;
|
|
132
|
+
case Standard:
|
|
133
|
+
return UIBarButtonItemVisibilityPriorityStandard;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(27_0)
|
|
137
|
+
|
|
121
138
|
+ (RNSScreenReplaceAnimation)RNSScreenReplaceAnimationFromCppEquivalent:
|
|
122
139
|
(react::RNSScreenReplaceAnimation)replaceAnimation
|
|
123
140
|
{
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#import <UIKit/UIKit.h>
|
|
4
|
+
#import "RNSDefines.h"
|
|
5
|
+
|
|
6
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
|
7
|
+
|
|
8
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
9
|
+
|
|
10
|
+
@protocol RNSNavigationBarLayoutDelegate <NSObject>
|
|
11
|
+
|
|
12
|
+
- (void)navigationBarDidLayoutSubviews:(UINavigationBar *)navigationBar;
|
|
13
|
+
|
|
14
|
+
@end
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Navigation bar used by the legacy stack (`RNSNavigationController`).
|
|
18
|
+
*
|
|
19
|
+
* It reports its layout passes to the `layoutDelegate`. On iOS 26+ UIKit can move the content of the navigation bar
|
|
20
|
+
* (e.g. on rotation or fold of iPhone Duo, or during the bar minimization on iOS 27) without any layout pass of the
|
|
21
|
+
* navigation controller's view, and layout of the bar is the only callback we receive in such a case.
|
|
22
|
+
*/
|
|
23
|
+
@interface RNSNavigationBar : UINavigationBar
|
|
24
|
+
|
|
25
|
+
@property (nonatomic, weak, nullable) id<RNSNavigationBarLayoutDelegate> layoutDelegate;
|
|
26
|
+
|
|
27
|
+
@end
|
|
28
|
+
|
|
29
|
+
NS_ASSUME_NONNULL_END
|
|
30
|
+
|
|
31
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#import "RNSNavigationBar.h"
|
|
2
|
+
|
|
3
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
|
4
|
+
|
|
5
|
+
@implementation RNSNavigationBar
|
|
6
|
+
|
|
7
|
+
- (void)layoutSubviews
|
|
8
|
+
{
|
|
9
|
+
[super layoutSubviews];
|
|
10
|
+
[_layoutDelegate navigationBarDidLayoutSubviews:self];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@end
|
|
14
|
+
|
|
15
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
package/ios/legacy/RNSScreen.mm
CHANGED
|
@@ -53,6 +53,9 @@ struct ContentWrapperBox {
|
|
|
53
53
|
|
|
54
54
|
@implementation RNSScreenView {
|
|
55
55
|
__weak RCTScrollViewComponentView *_sheetsScrollView;
|
|
56
|
+
/// Tag of `_sheetsScrollView` at the time we started observing it. Fabric changes the tag when it recycles
|
|
57
|
+
/// the view, so a mismatch means the instance now belongs to some other component.
|
|
58
|
+
NSInteger _sheetsScrollViewTag;
|
|
56
59
|
|
|
57
60
|
/// Up-to-date only when sheet is in `fitToContents` mode.
|
|
58
61
|
CGFloat _sheetContentHeight;
|
|
@@ -99,6 +102,7 @@ struct ContentWrapperBox {
|
|
|
99
102
|
_sheetExpandsWhenScrolledToEdge = YES;
|
|
100
103
|
#endif // !TARGET_OS_TV
|
|
101
104
|
_sheetsScrollView = nil;
|
|
105
|
+
_sheetsScrollViewTag = 0;
|
|
102
106
|
_sheetContentHeight = 0.0;
|
|
103
107
|
_markedForUnmountInCurrentTransaction = NO;
|
|
104
108
|
_synchronousShadowStateUpdatesEnabled = YES;
|
|
@@ -134,16 +138,24 @@ RNS_IGNORE_SUPER_CALL_END
|
|
|
134
138
|
if (_state != nullptr) {
|
|
135
139
|
RNSScreenStackHeaderConfig *config = [self findHeaderConfig];
|
|
136
140
|
|
|
137
|
-
//
|
|
138
|
-
//
|
|
141
|
+
// The content offset sent to the shadow tree must match the screen's native origin in the navigation controller's
|
|
142
|
+
// view. It is used by measurements & hit testing only, the size is delivered separately (`frameSize`).
|
|
143
|
+
// * On iOS 26+ (see `+[RNSScreenStackHeaderConfig screensExtendUnderOpaqueNavigationBar]`) the screen is always
|
|
144
|
+
// laid out under the navigation bar, so the origin is 0 and the `SafeAreaView` rendered by `ScreenStackItem`
|
|
145
|
+
// insets the content below an opaque bar. All branches below evaluate to 0 in that case.
|
|
146
|
+
// * Below iOS 26, when config.translucent == true, we use `edgesForExtendedLayout` and the screen is laid out
|
|
147
|
+
// under the navigation bar, therefore there is no need to set content offset in shadow tree.
|
|
148
|
+
// * Below iOS 26, in large title, ScrollView handles the offset of content so we cannot set it here also.
|
|
149
|
+
// TODO: Why is it assumed in comment above, that large title uses scrollview here? What if only SafeAreaView is
|
|
139
150
|
// used?
|
|
140
|
-
// * When config.translucent == true, we currently use `edgesForExtendedLayout` and the screen is laid out under the
|
|
141
|
-
// navigation bar, therefore there is no need to set content offset in shadow tree.
|
|
142
151
|
// * When this view is the modal root controller (presented in separate view hierarchy) it does not have navigation
|
|
143
152
|
// bar! We send non-zero size to JS, for some reason. TODO: this needs to be investigated.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
153
|
+
// * Otherwise the offset must match the actual native origin of the screen. We can not derive it from the
|
|
154
|
+
// navigation bar geometry, because UIKit does not always lay out the screen right below the navigation bar
|
|
155
|
+
// (e.g. on iOS 26 `edgesForExtendedLayout` ignores the navigation bar's origin offset).
|
|
156
|
+
// See https://github.com/software-mansion/react-native-screens-labs/issues/1841
|
|
157
|
+
const CGFloat effectiveContentOffsetY =
|
|
158
|
+
config.largeTitle || config.translucent || self.isPresentedAsNativeModal ? 0 : [self originInNavigationView].y;
|
|
147
159
|
|
|
148
160
|
auto newState = react::RNSScreenState{RCTSizeFromCGSize(self.bounds.size), {0, effectiveContentOffsetY}};
|
|
149
161
|
|
|
@@ -176,6 +188,17 @@ RNS_IGNORE_SUPER_CALL_END
|
|
|
176
188
|
}
|
|
177
189
|
}
|
|
178
190
|
|
|
191
|
+
// Returns origin of the screen in the coordinate space of its navigation controller's view, which matches
|
|
192
|
+
// the coordinate space of the screen stack in the shadow tree.
|
|
193
|
+
- (CGPoint)originInNavigationView
|
|
194
|
+
{
|
|
195
|
+
UIView *navigationView = _controller.navigationController.view;
|
|
196
|
+
if (navigationView == nil || ![self isDescendantOfView:navigationView]) {
|
|
197
|
+
return CGPointZero;
|
|
198
|
+
}
|
|
199
|
+
return [self convertPoint:CGPointZero toView:navigationView];
|
|
200
|
+
}
|
|
201
|
+
|
|
179
202
|
- (void)applyFrameCorrectionForDescendantScrollView
|
|
180
203
|
{
|
|
181
204
|
// A dismissed sheet can still receive a layout pass after React has deleted it. By then Fabric
|
|
@@ -194,6 +217,8 @@ RNS_IGNORE_SUPER_CALL_END
|
|
|
194
217
|
// we are going to overwrite it anyway.
|
|
195
218
|
[scrollView addObserver:self forKeyPath:@"bounds" options:0 context:nil];
|
|
196
219
|
}
|
|
220
|
+
// Refreshed even for the same instance: Fabric might have recycled it back into this sheet.
|
|
221
|
+
_sheetsScrollViewTag = scrollView != nil ? scrollView.tag : 0;
|
|
197
222
|
if (scrollView != nil) {
|
|
198
223
|
[self correctScrollViewFrame:scrollView withHeader:nil];
|
|
199
224
|
}
|
|
@@ -222,6 +247,16 @@ RNS_IGNORE_SUPER_CALL_END
|
|
|
222
247
|
return;
|
|
223
248
|
}
|
|
224
249
|
|
|
250
|
+
// The sheet's content can remove its scroll view while the sheet stays presented. Fabric then recycles
|
|
251
|
+
// the instance (possibly into another screen), which changes its tag. Stop observing it instead of
|
|
252
|
+
// forcing it to this screen's frame. See #4785.
|
|
253
|
+
if (scrollView.tag != _sheetsScrollViewTag) {
|
|
254
|
+
[scrollView removeObserver:self forKeyPath:@"bounds" context:nil];
|
|
255
|
+
_sheetsScrollView = nil;
|
|
256
|
+
_sheetsScrollViewTag = 0;
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
225
260
|
RNSScreenContentWrapper *_Nullable contentWrapper = _contentWrapperBox.contentWrapper;
|
|
226
261
|
if (contentWrapper != nil && [contentWrapper coerceChildScrollViewComponentSizeToSize:self.frame.size]) {
|
|
227
262
|
return;
|
|
@@ -784,6 +819,7 @@ RNS_IGNORE_SUPER_CALL_END
|
|
|
784
819
|
if (_sheetsScrollView != nil) {
|
|
785
820
|
[_sheetsScrollView removeObserver:self forKeyPath:@"bounds" context:nil];
|
|
786
821
|
_sheetsScrollView = nil;
|
|
822
|
+
_sheetsScrollViewTag = 0;
|
|
787
823
|
}
|
|
788
824
|
|
|
789
825
|
// We want to run after container updates are performed (transitions etc.)
|
|
@@ -1428,6 +1464,7 @@ Class<RCTComponentViewProtocol> RNSScreenCls(void)
|
|
|
1428
1464
|
BOOL _isSwiping;
|
|
1429
1465
|
BOOL _shouldNotify;
|
|
1430
1466
|
BOOL _isRemovedFromParent;
|
|
1467
|
+
BOOL _hasNotifiedDismissed;
|
|
1431
1468
|
}
|
|
1432
1469
|
|
|
1433
1470
|
#pragma mark - Common
|
|
@@ -1439,6 +1476,7 @@ Class<RCTComponentViewProtocol> RNSScreenCls(void)
|
|
|
1439
1476
|
_fakeView = [UIView new];
|
|
1440
1477
|
_shouldNotify = YES;
|
|
1441
1478
|
_isRemovedFromParent = NO;
|
|
1479
|
+
_hasNotifiedDismissed = NO;
|
|
1442
1480
|
}
|
|
1443
1481
|
return self;
|
|
1444
1482
|
}
|
|
@@ -1535,7 +1573,7 @@ Class<RCTComponentViewProtocol> RNSScreenCls(void)
|
|
|
1535
1573
|
[self.screenView notifyDismissCancelledWithDismissCount:_dismissCount];
|
|
1536
1574
|
} else {
|
|
1537
1575
|
// screen dismissed, send event
|
|
1538
|
-
[self
|
|
1576
|
+
[self notifyDismissedIfNeeded];
|
|
1539
1577
|
}
|
|
1540
1578
|
}
|
|
1541
1579
|
// same flow as in viewDidAppear
|
|
@@ -1553,10 +1591,12 @@ Class<RCTComponentViewProtocol> RNSScreenCls(void)
|
|
|
1553
1591
|
[super viewDidLayoutSubviews];
|
|
1554
1592
|
|
|
1555
1593
|
// The below code makes the screen view adapt dimensions provided by the system. We take these
|
|
1556
|
-
// into account only when the view is mounted under RNSNavigationController in which case
|
|
1557
|
-
//
|
|
1558
|
-
//
|
|
1559
|
-
//
|
|
1594
|
+
// into account only when the view is mounted under RNSNavigationController, in which case the
|
|
1595
|
+
// navigation controller sizes the screen (below iOS 26 an opaque navigation bar is excluded from
|
|
1596
|
+
// the screen's frame, on iOS 26+ the screen always spans under the bar, see
|
|
1597
|
+
// `+[RNSScreenStackHeaderConfig screensExtendUnderOpaqueNavigationBar]`), and in the case when
|
|
1598
|
+
// screen is shown as a native modal, as the final dimensions of the modal on iOS 12+ are shorter
|
|
1599
|
+
// than the screen size.
|
|
1560
1600
|
BOOL isDisplayedWithinUINavController = [self.parentViewController isKindOfClass:[RNSNavigationController class]];
|
|
1561
1601
|
BOOL isTabScreen = [self.parentViewController isKindOfClass:RNSTabBarController.class];
|
|
1562
1602
|
|
|
@@ -1620,6 +1660,12 @@ Class<RCTComponentViewProtocol> RNSScreenCls(void)
|
|
|
1620
1660
|
return 0;
|
|
1621
1661
|
}
|
|
1622
1662
|
|
|
1663
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(27_0) && !TARGET_OS_TV
|
|
1664
|
+
if (@available(iOS 27.0, *)) {
|
|
1665
|
+
return [self calculateMinimizationAwareHeaderHeightInNavigationController:navctr];
|
|
1666
|
+
}
|
|
1667
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(27_0) && !TARGET_OS_TV
|
|
1668
|
+
|
|
1623
1669
|
CGFloat navbarHeight = navctr.navigationBar.frame.size.height;
|
|
1624
1670
|
#if !TARGET_OS_TV
|
|
1625
1671
|
CGFloat navbarInset = navctr.navigationBar.frame.origin.y;
|
|
@@ -1631,6 +1677,35 @@ Class<RCTComponentViewProtocol> RNSScreenCls(void)
|
|
|
1631
1677
|
return navbarHeight + navbarInset;
|
|
1632
1678
|
}
|
|
1633
1679
|
|
|
1680
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(27_0) && !TARGET_OS_TV
|
|
1681
|
+
// On iOS 27 the navigation bar can minimize in response to scrolling (`UIBarMinimization`). The frame of
|
|
1682
|
+
// `UINavigationBar` does not follow the minimization, only its subviews (background, content view, large title,
|
|
1683
|
+
// search bar) do - they are shifted up within the bar. Therefore we measure the bottom edge of the subviews
|
|
1684
|
+
// instead, in the coordinate space of the navigation controller's view. The value is clamped to the bar's frame,
|
|
1685
|
+
// which is the maximum extent of the bar in the expanded state.
|
|
1686
|
+
- (CGFloat)calculateMinimizationAwareHeaderHeightInNavigationController:(UINavigationController *)navctr
|
|
1687
|
+
API_AVAILABLE(ios(27.0))
|
|
1688
|
+
{
|
|
1689
|
+
UINavigationBar *navbar = navctr.navigationBar;
|
|
1690
|
+
CGFloat navbarMaxY = CGRectGetMaxY([navbar convertRect:navbar.bounds toView:navctr.view]);
|
|
1691
|
+
CGFloat maxY = -CGFLOAT_MAX;
|
|
1692
|
+
|
|
1693
|
+
for (UIView *subview in navbar.subviews) {
|
|
1694
|
+
if (subview.isHidden || CGRectIsEmpty(subview.frame)) {
|
|
1695
|
+
continue;
|
|
1696
|
+
}
|
|
1697
|
+
maxY = MAX(maxY, CGRectGetMaxY([navbar convertRect:subview.frame toView:navctr.view]));
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
if (maxY == -CGFLOAT_MAX) {
|
|
1701
|
+
// No measurable subviews, same as the pre-iOS 27 formula.
|
|
1702
|
+
return navbarMaxY;
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
return MIN(maxY, navbarMaxY);
|
|
1706
|
+
}
|
|
1707
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(27_0) && !TARGET_OS_TV
|
|
1708
|
+
|
|
1634
1709
|
- (void)calculateAndNotifyHeaderHeightChangeIsModal:(BOOL)isModal
|
|
1635
1710
|
{
|
|
1636
1711
|
CGFloat totalHeight = [self calculateHeaderHeightIsModal:isModal];
|
|
@@ -1698,6 +1773,34 @@ Class<RCTComponentViewProtocol> RNSScreenCls(void)
|
|
|
1698
1773
|
_isRemovedFromParent = YES;
|
|
1699
1774
|
}
|
|
1700
1775
|
|
|
1776
|
+
- (BOOL)isNativelyDismissedFromContainer
|
|
1777
|
+
{
|
|
1778
|
+
if (self.presentingViewController != nil) {
|
|
1779
|
+
return NO;
|
|
1780
|
+
}
|
|
1781
|
+
if (self.parentViewController == nil) {
|
|
1782
|
+
return YES;
|
|
1783
|
+
}
|
|
1784
|
+
if ([self.parentViewController isKindOfClass:UINavigationController.class]) {
|
|
1785
|
+
UINavigationController *navigationController = (UINavigationController *)self.parentViewController;
|
|
1786
|
+
return ![navigationController.viewControllers containsObject:self];
|
|
1787
|
+
}
|
|
1788
|
+
return NO;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
- (void)notifyDismissedIfNeeded
|
|
1792
|
+
{
|
|
1793
|
+
if (_hasNotifiedDismissed || self.screenView.preventNativeDismiss) {
|
|
1794
|
+
return;
|
|
1795
|
+
}
|
|
1796
|
+
if (![self isNativelyDismissedFromContainer]) {
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1799
|
+
_hasNotifiedDismissed = YES;
|
|
1800
|
+
_isRemovedFromParent = YES;
|
|
1801
|
+
[self.screenView notifyDismissedWithCount:_dismissCount];
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1701
1804
|
#pragma mark - transition progress related methods
|
|
1702
1805
|
|
|
1703
1806
|
- (void)setupProgressNotification
|
|
@@ -1720,12 +1823,19 @@ Class<RCTComponentViewProtocol> RNSScreenCls(void)
|
|
|
1720
1823
|
[self->_animationTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
|
1721
1824
|
};
|
|
1722
1825
|
|
|
1826
|
+
BOOL notifyDismissWhenTransitionEnds = _closing;
|
|
1723
1827
|
[self.transitionCoordinator
|
|
1724
1828
|
animateAlongsideTransition:animation
|
|
1725
1829
|
completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
|
1726
1830
|
[self->_animationTimer setPaused:YES];
|
|
1727
1831
|
[self->_animationTimer invalidate];
|
|
1728
1832
|
[self->_fakeView removeFromSuperview];
|
|
1833
|
+
// iOS 27 can skip viewDidDisappear when a tab switch
|
|
1834
|
+
// interrupts popToRoot. If this screen was popped,
|
|
1835
|
+
// notify JS when the transition ends.
|
|
1836
|
+
if (notifyDismissWhenTransitionEnds) {
|
|
1837
|
+
[self notifyDismissedIfNeeded];
|
|
1838
|
+
}
|
|
1729
1839
|
}];
|
|
1730
1840
|
}
|
|
1731
1841
|
}
|
|
@@ -53,6 +53,9 @@ namespace react = facebook::react;
|
|
|
53
53
|
{
|
|
54
54
|
UIViewController *controller = screenCtrl;
|
|
55
55
|
float headerHeightErrata = 0.f;
|
|
56
|
+
// When screens extend under opaque navigation bars (iOS 26+), the `SafeAreaView` rendered inside this wrapper insets
|
|
57
|
+
// the content below the bar, so the bar height is already part of the wrapper's frame and must not be added again.
|
|
58
|
+
const BOOL wrapperFrameIncludesNavigationBar = [RNSScreenStackHeaderConfig screensExtendUnderOpaqueNavigationBar];
|
|
56
59
|
|
|
57
60
|
do {
|
|
58
61
|
if ([controller isKindOfClass:RNSScreen.class]) {
|
|
@@ -60,7 +63,7 @@ namespace react = facebook::react;
|
|
|
60
63
|
if ([currentScreen.screenView registerContentWrapper:self contentHeightErrata:headerHeightErrata]) {
|
|
61
64
|
break;
|
|
62
65
|
}
|
|
63
|
-
} else if ([controller isKindOfClass:RNSNavigationController.class]) {
|
|
66
|
+
} else if (!wrapperFrameIncludesNavigationBar && [controller isKindOfClass:RNSNavigationController.class]) {
|
|
64
67
|
RNSNavigationController *navigationController = static_cast<RNSNavigationController *>(controller);
|
|
65
68
|
UINavigationBar *navigationBar = navigationController.navigationBar;
|
|
66
69
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
|
|
13
13
|
#import "RCTSurfaceTouchHandler+RNSUtility.h"
|
|
14
14
|
#import "RNSDefines.h"
|
|
15
|
+
#import "RNSNavigationBar.h"
|
|
15
16
|
#import "RNSPercentDrivenInteractiveTransition.h"
|
|
16
17
|
#import "RNSScreen.h"
|
|
17
18
|
#import "RNSScreenStackAnimator.h"
|
|
@@ -24,6 +25,10 @@
|
|
|
24
25
|
#import "UIView+RNSUtility.h"
|
|
25
26
|
#import "integrations/RNSDismissibleModalProtocol.h"
|
|
26
27
|
|
|
28
|
+
#if TARGET_OS_TV
|
|
29
|
+
#import <React/RCTTVRemoteHandler.h>
|
|
30
|
+
#endif // TARGET_OS_TV
|
|
31
|
+
|
|
27
32
|
namespace react = facebook::react;
|
|
28
33
|
|
|
29
34
|
@interface RNSScreenStackView () <UINavigationControllerDelegate,
|
|
@@ -36,9 +41,36 @@ namespace react = facebook::react;
|
|
|
36
41
|
@property (nonatomic) BOOL updatingModals;
|
|
37
42
|
@property (nonatomic) BOOL scheduleModalsUpdate;
|
|
38
43
|
|
|
44
|
+
#if TARGET_OS_TV
|
|
45
|
+
@property (nonatomic, assign) BOOL disableDefaultMenuAction;
|
|
46
|
+
@property (nonatomic, assign) BOOL observingTVMenuKeyNotifications;
|
|
47
|
+
#endif // TARGET_OS_TV
|
|
48
|
+
|
|
49
|
+
@end
|
|
50
|
+
|
|
51
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
|
52
|
+
@interface RNSNavigationController () <RNSNavigationBarLayoutDelegate>
|
|
39
53
|
@end
|
|
54
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
|
40
55
|
|
|
41
|
-
@implementation RNSNavigationController
|
|
56
|
+
@implementation RNSNavigationController {
|
|
57
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
|
58
|
+
CGRect _lastNavigationBarFrame;
|
|
59
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
- (instancetype)init
|
|
63
|
+
{
|
|
64
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
|
65
|
+
self = [super initWithNavigationBarClass:RNSNavigationBar.class toolbarClass:nil];
|
|
66
|
+
if (self != nil && [self.navigationBar isKindOfClass:RNSNavigationBar.class]) {
|
|
67
|
+
static_cast<RNSNavigationBar *>(self.navigationBar).layoutDelegate = self;
|
|
68
|
+
}
|
|
69
|
+
#else // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
|
70
|
+
self = [super init];
|
|
71
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) && !TARGET_OS_TV
|
|
72
|
+
return self;
|
|
73
|
+
}
|
|
42
74
|
|
|
43
75
|
#if !TARGET_OS_TV
|
|
44
76
|
- (UIViewController *)childViewControllerForStatusBarStyle
|
|
@@ -59,25 +91,34 @@ namespace react = facebook::react;
|
|
|
59
91
|
- (void)viewDidLayoutSubviews
|
|
60
92
|
{
|
|
61
93
|
[super viewDidLayoutSubviews];
|
|
94
|
+
|
|
95
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
|
|
96
|
+
if (@available(iOS 26.0, *)) {
|
|
97
|
+
[self requestLayoutIfNavigationBarFrameChanged];
|
|
98
|
+
}
|
|
99
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
|
|
100
|
+
|
|
62
101
|
if ([self.topViewController isKindOfClass:[RNSScreen class]]) {
|
|
63
102
|
RNSScreen *screenController = (RNSScreen *)self.topViewController;
|
|
64
|
-
|
|
65
|
-
(screenController.presentedViewController != nil &&
|
|
66
|
-
![screenController.presentedViewController isBeingDismissed]);
|
|
67
|
-
BOOL isPresentingSearchController =
|
|
68
|
-
[screenController.presentedViewController isKindOfClass:UISearchController.class];
|
|
69
|
-
|
|
70
|
-
// Calculate header height during simple transition from one screen to another.
|
|
71
|
-
// If RNSScreen includes a navigation controller of type RNSNavigationController, it should not calculate
|
|
72
|
-
// header height, as it could have nested stack.
|
|
73
|
-
if (![screenController hasNestedStack] && (isPresentingSearchController || isNotDismissingModal)) {
|
|
74
|
-
[screenController calculateAndNotifyHeaderHeightChangeIsModal:NO];
|
|
75
|
-
}
|
|
76
|
-
|
|
103
|
+
[self notifyHeaderHeightChangeToScreen:screenController];
|
|
77
104
|
[self maybeUpdateHeaderLayoutInfoInShadowTree:screenController];
|
|
78
105
|
}
|
|
79
106
|
}
|
|
80
107
|
|
|
108
|
+
- (void)notifyHeaderHeightChangeToScreen:(RNSScreen *)screenController
|
|
109
|
+
{
|
|
110
|
+
BOOL isNotDismissingModal = screenController.presentedViewController == nil ||
|
|
111
|
+
(screenController.presentedViewController != nil && ![screenController.presentedViewController isBeingDismissed]);
|
|
112
|
+
BOOL isPresentingSearchController = [screenController.presentedViewController isKindOfClass:UISearchController.class];
|
|
113
|
+
|
|
114
|
+
// Calculate header height during simple transition from one screen to another.
|
|
115
|
+
// If RNSScreen includes a navigation controller of type RNSNavigationController, it should not calculate
|
|
116
|
+
// header height, as it could have nested stack.
|
|
117
|
+
if (![screenController hasNestedStack] && (isPresentingSearchController || isNotDismissingModal)) {
|
|
118
|
+
[screenController calculateAndNotifyHeaderHeightChangeIsModal:NO];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
81
122
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
|
|
82
123
|
{
|
|
83
124
|
return [self topViewController].supportedInterfaceOrientations;
|
|
@@ -116,7 +157,61 @@ namespace react = facebook::react;
|
|
|
116
157
|
|
|
117
158
|
[headerConfig updateHeaderStateInShadowTreeInContextOfNavigationBar:self.navigationBar];
|
|
118
159
|
}
|
|
119
|
-
|
|
160
|
+
|
|
161
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
|
|
162
|
+
- (void)requestLayoutIfNavigationBarFrameChanged API_AVAILABLE(ios(26.0))
|
|
163
|
+
{
|
|
164
|
+
// UIKit positions the navigation bar during layout of our view, but on iOS 26+ it does so after it has computed
|
|
165
|
+
// the safe area insets of the top view controller. The insets are therefore derived from the previous frame of
|
|
166
|
+
// the bar and they are not corrected until the next layout pass, which nobody requests.
|
|
167
|
+
// Since on iOS 26+ the screen is always laid out under the navigation bar, anything that relies on the insets
|
|
168
|
+
// (`SafeAreaView` rendered by `ScreenStackItem`, content inset adjustment of a scroll view) is misplaced by
|
|
169
|
+
// the distance the bar has travelled.
|
|
170
|
+
//
|
|
171
|
+
// When the frame of the bar has changed, we request another layout pass, in which UIKit computes the insets with
|
|
172
|
+
// the bar already in place. It runs in the same frame. The frame of the bar does not depend on the insets of
|
|
173
|
+
// the top view controller, so the bar is not moved in the additional pass and we do not request yet another one.
|
|
174
|
+
const CGRect navigationBarFrame = self.navigationBar.frame;
|
|
175
|
+
if (!CGRectEqualToRect(navigationBarFrame, _lastNavigationBarFrame)) {
|
|
176
|
+
_lastNavigationBarFrame = navigationBarFrame;
|
|
177
|
+
[self.view setNeedsLayout];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
#pragma mark - RNSNavigationBarLayoutDelegate
|
|
182
|
+
|
|
183
|
+
- (void)navigationBarDidLayoutSubviews:(UINavigationBar *)navigationBar
|
|
184
|
+
{
|
|
185
|
+
// On iOS 26+ UIKit can position the content of the navigation bar after `viewDidLayoutSubviews`, in a layout pass
|
|
186
|
+
// that follows layout of the bar itself (e.g. title view on rotation of iPhone Duo), or without any layout pass of
|
|
187
|
+
// our view at all (bar minimization on iOS 27). None of our views receives a callback when it is moved this way,
|
|
188
|
+
// therefore we request layout of the header subviews. They are laid out later in the same layout pass, after their
|
|
189
|
+
// ancestors, and update their position in the shadow tree then.
|
|
190
|
+
// See https://github.com/software-mansion/react-native-screens-labs/issues/1841
|
|
191
|
+
if (@available(iOS 26.0, *)) {
|
|
192
|
+
if (![self.topViewController isKindOfClass:[RNSScreen class]]) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
#if RNS_IPHONE_OS_VERSION_AVAILABLE(27_0)
|
|
197
|
+
// The bar minimization (iOS 27+) changes the visible height of the bar without changing its frame and without
|
|
198
|
+
// layout of our view, so this is the only place where we can follow it.
|
|
199
|
+
if (@available(iOS 27.0, *)) {
|
|
200
|
+
[self notifyHeaderHeightChangeToScreen:static_cast<RNSScreen *>(self.topViewController)];
|
|
201
|
+
}
|
|
202
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(27_0)
|
|
203
|
+
|
|
204
|
+
auto headerConfig = static_cast<RNSScreen *>(self.topViewController).screenView.findHeaderConfig;
|
|
205
|
+
if (headerConfig == nil || !headerConfig.shouldHeaderBeVisible) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
[headerConfig setNeedsLayoutForHeaderSubviewsInNavigationBar:navigationBar];
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
#endif // RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
|
|
214
|
+
#endif // !TARGET_OS_TV
|
|
120
215
|
|
|
121
216
|
- (void)willMoveToParentViewController:(UIViewController *)parent
|
|
122
217
|
{
|
|
@@ -283,8 +378,81 @@ RNS_IGNORE_SUPER_CALL_END
|
|
|
283
378
|
[super didMoveToWindow];
|
|
284
379
|
// for handling nested stacks
|
|
285
380
|
[self maybeAddToParentAndUpdateContainer];
|
|
381
|
+
#if TARGET_OS_TV
|
|
382
|
+
if (self.window != nil) {
|
|
383
|
+
[self registerForTVMenuKeyNotificationsIfNeeded];
|
|
384
|
+
[self syncTVMenuKeyHandling];
|
|
385
|
+
} else {
|
|
386
|
+
[self unregisterForTVMenuKeyNotificationsIfNeeded];
|
|
387
|
+
}
|
|
388
|
+
#endif // TARGET_OS_TV
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
#if TARGET_OS_TV
|
|
392
|
+
|
|
393
|
+
- (void)registerForTVMenuKeyNotificationsIfNeeded
|
|
394
|
+
{
|
|
395
|
+
if (_observingTVMenuKeyNotifications) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
_observingTVMenuKeyNotifications = YES;
|
|
399
|
+
NSNotificationCenter *center = NSNotificationCenter.defaultCenter;
|
|
400
|
+
[center addObserver:self
|
|
401
|
+
selector:@selector(handleTVMenuKeyNotification:)
|
|
402
|
+
name:RCTTVEnableMenuKeyNotification
|
|
403
|
+
object:nil];
|
|
404
|
+
[center addObserver:self
|
|
405
|
+
selector:@selector(handleTVMenuKeyNotification:)
|
|
406
|
+
name:RCTTVDisableMenuKeyNotification
|
|
407
|
+
object:nil];
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
- (void)unregisterForTVMenuKeyNotificationsIfNeeded
|
|
411
|
+
{
|
|
412
|
+
if (!_observingTVMenuKeyNotifications) {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
_observingTVMenuKeyNotifications = NO;
|
|
416
|
+
NSNotificationCenter *center = NSNotificationCenter.defaultCenter;
|
|
417
|
+
[center removeObserver:self name:RCTTVEnableMenuKeyNotification object:nil];
|
|
418
|
+
[center removeObserver:self name:RCTTVDisableMenuKeyNotification object:nil];
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
- (void)handleTVMenuKeyNotification:(NSNotification *)notification
|
|
422
|
+
{
|
|
423
|
+
[self syncTVMenuKeyHandling];
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
- (BOOL)shouldDisableUIKitMenuBackGesture
|
|
427
|
+
{
|
|
428
|
+
return _disableDefaultMenuAction && [RCTTVRemoteHandler useMenuKey];
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
- (nullable UITapGestureRecognizer *)uiKitMenuBackGestureRecognizer
|
|
432
|
+
{
|
|
433
|
+
for (UIGestureRecognizer *recognizer in _controller.view.gestureRecognizers) {
|
|
434
|
+
if (![recognizer isKindOfClass:UITapGestureRecognizer.class]) {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
UITapGestureRecognizer *tapRecognizer = (UITapGestureRecognizer *)recognizer;
|
|
438
|
+
if ([tapRecognizer.allowedPressTypes containsObject:@(UIPressTypeMenu)]) {
|
|
439
|
+
return tapRecognizer;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return nil;
|
|
286
443
|
}
|
|
287
444
|
|
|
445
|
+
- (void)syncTVMenuKeyHandling
|
|
446
|
+
{
|
|
447
|
+
UITapGestureRecognizer *menuBackGesture = [self uiKitMenuBackGestureRecognizer];
|
|
448
|
+
if (menuBackGesture == nil) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
menuBackGesture.enabled = ![self shouldDisableUIKitMenuBackGesture];
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
#endif // TARGET_OS_TV
|
|
455
|
+
|
|
288
456
|
- (void)maybeAddToParentAndUpdateContainer
|
|
289
457
|
{
|
|
290
458
|
BOOL wasScreenMounted = _controller.parentViewController != nil;
|
|
@@ -997,6 +1165,15 @@ RNS_IGNORE_SUPER_CALL_END
|
|
|
997
1165
|
}
|
|
998
1166
|
#endif
|
|
999
1167
|
|
|
1168
|
+
#if TARGET_OS_TV
|
|
1169
|
+
- (void)navigationController:(UINavigationController *)navigationController
|
|
1170
|
+
didShowViewController:(UIViewController *)viewController
|
|
1171
|
+
animated:(BOOL)animated
|
|
1172
|
+
{
|
|
1173
|
+
[self syncTVMenuKeyHandling];
|
|
1174
|
+
}
|
|
1175
|
+
#endif // TARGET_OS_TV
|
|
1176
|
+
|
|
1000
1177
|
- (void)markChildUpdated
|
|
1001
1178
|
{
|
|
1002
1179
|
// In native stack this should be called only for `preload` purposes.
|
|
@@ -1279,6 +1456,13 @@ RNS_IGNORE_SUPER_CALL_END
|
|
|
1279
1456
|
_controller.view.backgroundColor = _nativeContainerBackgroundColor;
|
|
1280
1457
|
}
|
|
1281
1458
|
|
|
1459
|
+
#if TARGET_OS_TV
|
|
1460
|
+
if (newScreenProps.disableDefaultMenuAction != oldScreenProps.disableDefaultMenuAction) {
|
|
1461
|
+
_disableDefaultMenuAction = newScreenProps.disableDefaultMenuAction;
|
|
1462
|
+
[self syncTVMenuKeyHandling];
|
|
1463
|
+
}
|
|
1464
|
+
#endif // TARGET_OS_TV
|
|
1465
|
+
|
|
1282
1466
|
[super updateProps:props oldProps:oldProps];
|
|
1283
1467
|
}
|
|
1284
1468
|
|
|
@@ -1375,6 +1559,9 @@ RNS_IGNORE_SUPER_CALL_END
|
|
|
1375
1559
|
- (void)prepareForRecycle
|
|
1376
1560
|
{
|
|
1377
1561
|
[super prepareForRecycle];
|
|
1562
|
+
#if TARGET_OS_TV
|
|
1563
|
+
[self unregisterForTVMenuKeyNotificationsIfNeeded];
|
|
1564
|
+
#endif // TARGET_OS_TV
|
|
1378
1565
|
_reactSubviews = [NSMutableArray new];
|
|
1379
1566
|
|
|
1380
1567
|
for (UIViewController *controller in _presentedModals) {
|