@amazon-devices/react-native-screens 2.0.1758683737
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/LICENSE +7 -0
- package/README.md +223 -0
- package/RNScreens.podspec +53 -0
- package/SystemBundles/8f5a820b958535e533acb38dbc0c72c1837721b9db075f4a1740e42b9fee3910.bundle +33668 -0
- package/SystemBundles/8f5a820b958535e533acb38dbc0c72c1837721b9db075f4a1740e42b9fee3910.map +1 -0
- package/SystemModules/amzn__react-native-screens.modules.txt +101 -0
- package/SystemModules/amzn__react-native-screens.private.modules.txt +244 -0
- package/SystemModules/keplerscript-system-bundle-config.json +7 -0
- package/THIRD_PARTY_NOTICES.txt +707 -0
- package/android/build.gradle +133 -0
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +49 -0
- package/android/src/main/AndroidManifest.xml +5 -0
- package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +77 -0
- package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +29 -0
- package/android/src/main/java/com/swmansion/rnscreens/FragmentHolder.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +21 -0
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +289 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +372 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +40 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +21 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +331 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +336 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +282 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +15 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +398 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +204 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +38 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +41 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +75 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +186 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +296 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +19 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +133 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +178 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +67 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +20 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +32 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +28 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +12 -0
- package/android/src/main/jni/CMakeLists.txt +72 -0
- package/android/src/main/jni/rnscreens.cpp +16 -0
- package/android/src/main/jni/rnscreens.h +28 -0
- package/android/src/main/res/base/anim/rns_default_enter_in.xml +18 -0
- package/android/src/main/res/base/anim/rns_default_enter_out.xml +19 -0
- package/android/src/main/res/base/anim/rns_default_exit_in.xml +17 -0
- package/android/src/main/res/base/anim/rns_default_exit_out.xml +18 -0
- package/android/src/main/res/base/anim/rns_fade_from_bottom.xml +14 -0
- package/android/src/main/res/base/anim/rns_fade_in.xml +7 -0
- package/android/src/main/res/base/anim/rns_fade_out.xml +7 -0
- package/android/src/main/res/base/anim/rns_fade_to_bottom.xml +15 -0
- package/android/src/main/res/base/anim/rns_no_animation_20.xml +6 -0
- package/android/src/main/res/base/anim/rns_no_animation_250.xml +7 -0
- package/android/src/main/res/base/anim/rns_no_animation_350.xml +6 -0
- package/android/src/main/res/base/anim/rns_no_animation_medium.xml +7 -0
- package/android/src/main/res/base/anim/rns_slide_in_from_bottom.xml +7 -0
- package/android/src/main/res/base/anim/rns_slide_in_from_left.xml +5 -0
- package/android/src/main/res/base/anim/rns_slide_in_from_right.xml +5 -0
- package/android/src/main/res/base/anim/rns_slide_out_to_bottom.xml +7 -0
- package/android/src/main/res/base/anim/rns_slide_out_to_left.xml +5 -0
- package/android/src/main/res/base/anim/rns_slide_out_to_right.xml +5 -0
- package/android/src/main/res/base/anim/rns_standard_accelerate_interpolator.xml +6 -0
- package/android/src/main/res/v33/anim-v33/rns_default_enter_in.xml +38 -0
- package/android/src/main/res/v33/anim-v33/rns_default_enter_out.xml +38 -0
- package/android/src/main/res/v33/anim-v33/rns_default_exit_in.xml +38 -0
- package/android/src/main/res/v33/anim-v33/rns_default_exit_out.xml +38 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +111 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +44 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +107 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +42 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerDelegate.java +31 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerInterface.java +17 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerDelegate.java +25 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerInterface.java +16 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +41 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +9 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +30 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +14 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +45 -0
- package/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.h +11 -0
- package/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.mm +14 -0
- package/ios/RNSConvert.h +36 -0
- package/ios/RNSConvert.mm +154 -0
- package/ios/RNSEnums.h +71 -0
- package/ios/RNSFullWindowOverlay.h +34 -0
- package/ios/RNSFullWindowOverlay.mm +241 -0
- package/ios/RNSScreen.h +144 -0
- package/ios/RNSScreen.mm +1599 -0
- package/ios/RNSScreenContainer.h +45 -0
- package/ios/RNSScreenContainer.mm +343 -0
- package/ios/RNSScreenNavigationContainer.h +16 -0
- package/ios/RNSScreenNavigationContainer.mm +66 -0
- package/ios/RNSScreenStack.h +37 -0
- package/ios/RNSScreenStack.mm +1111 -0
- package/ios/RNSScreenStackAnimator.h +8 -0
- package/ios/RNSScreenStackAnimator.mm +320 -0
- package/ios/RNSScreenStackHeaderConfig.h +74 -0
- package/ios/RNSScreenStackHeaderConfig.mm +967 -0
- package/ios/RNSScreenStackHeaderSubview.h +44 -0
- package/ios/RNSScreenStackHeaderSubview.mm +147 -0
- package/ios/RNSScreenWindowTraits.h +26 -0
- package/ios/RNSScreenWindowTraits.mm +266 -0
- package/ios/RNSSearchBar.h +43 -0
- package/ios/RNSSearchBar.mm +465 -0
- package/ios/RNScreens.xcodeproj/project.pbxproj +461 -0
- package/ios/UIViewController+RNScreens.h +9 -0
- package/ios/UIViewController+RNScreens.mm +78 -0
- package/ios/UIWindow+RNScreens.h +9 -0
- package/ios/UIWindow+RNScreens.mm +17 -0
- package/ios/events/RNSHeaderHeightChangeEvent.h +8 -0
- package/ios/events/RNSHeaderHeightChangeEvent.mm +44 -0
- package/ios/events/RNSScreenViewEvent.h +12 -0
- package/ios/events/RNSScreenViewEvent.mm +59 -0
- package/ios/utils/RNSUIBarButtonItem.h +5 -0
- package/ios/utils/RNSUIBarButtonItem.mm +22 -0
- package/kepler-compatibility.json +8 -0
- package/kepler-transformed-package-info.json +3 -0
- package/lib/commonjs/TransitionProgressContext.js +11 -0
- package/lib/commonjs/TransitionProgressContext.js.map +1 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +11 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +33 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js +70 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +11 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +31 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +12 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js +35 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/SearchBarNativeComponent.js +19 -0
- package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -0
- package/lib/commonjs/index.js +147 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/index.native.js +407 -0
- package/lib/commonjs/index.native.js.map +1 -0
- package/lib/commonjs/native-stack/index.js +49 -0
- package/lib/commonjs/native-stack/index.js.map +1 -0
- package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js +75 -0
- package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js.map +1 -0
- package/lib/commonjs/native-stack/types.js +6 -0
- package/lib/commonjs/native-stack/types.js.map +1 -0
- package/lib/commonjs/native-stack/utils/AnimatedHeaderHeightContext.js +12 -0
- package/lib/commonjs/native-stack/utils/AnimatedHeaderHeightContext.js.map +1 -0
- package/lib/commonjs/native-stack/utils/HeaderHeightContext.js +12 -0
- package/lib/commonjs/native-stack/utils/HeaderHeightContext.js.map +1 -0
- package/lib/commonjs/native-stack/utils/SafeAreaProviderCompat.js +75 -0
- package/lib/commonjs/native-stack/utils/SafeAreaProviderCompat.js.map +1 -0
- package/lib/commonjs/native-stack/utils/getDefaultHeaderHeight.js +35 -0
- package/lib/commonjs/native-stack/utils/getDefaultHeaderHeight.js.map +1 -0
- package/lib/commonjs/native-stack/utils/useAnimatedHeaderHeight.js +19 -0
- package/lib/commonjs/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -0
- package/lib/commonjs/native-stack/utils/useBackPressSubscription.js +54 -0
- package/lib/commonjs/native-stack/utils/useBackPressSubscription.js.map +1 -0
- package/lib/commonjs/native-stack/utils/useHeaderHeight.js +19 -0
- package/lib/commonjs/native-stack/utils/useHeaderHeight.js.map +1 -0
- package/lib/commonjs/native-stack/views/FontProcessor.js +21 -0
- package/lib/commonjs/native-stack/views/FontProcessor.js.map +1 -0
- package/lib/commonjs/native-stack/views/HeaderConfig.js +141 -0
- package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js +354 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedHeaderHeightContext.js +12 -0
- package/lib/commonjs/reanimated/ReanimatedHeaderHeightContext.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +101 -0
- package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedScreen.js +22 -0
- package/lib/commonjs/reanimated/ReanimatedScreen.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +47 -0
- package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedTransitionProgressContext.js +12 -0
- package/lib/commonjs/reanimated/ReanimatedTransitionProgressContext.js.map +1 -0
- package/lib/commonjs/reanimated/index.js +28 -0
- package/lib/commonjs/reanimated/index.js.map +1 -0
- package/lib/commonjs/reanimated/useReanimatedHeaderHeight.js +19 -0
- package/lib/commonjs/reanimated/useReanimatedHeaderHeight.js.map +1 -0
- package/lib/commonjs/reanimated/useReanimatedTransitionProgress.js +19 -0
- package/lib/commonjs/reanimated/useReanimatedTransitionProgress.js.map +1 -0
- package/lib/commonjs/types.js +6 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/useTransitionProgress.js +19 -0
- package/lib/commonjs/useTransitionProgress.js.map +1 -0
- package/lib/commonjs/utils.js +21 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/TransitionProgressContext.js +3 -0
- package/lib/module/TransitionProgressContext.js.map +1 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js +4 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js +25 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenNativeComponent.js +63 -0
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +4 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +23 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +7 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js +28 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -0
- package/lib/module/fabric/SearchBarNativeComponent.js +10 -0
- package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -0
- package/lib/module/index.js +67 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/index.native.js +410 -0
- package/lib/module/index.native.js.map +1 -0
- package/lib/module/native-stack/index.js +22 -0
- package/lib/module/native-stack/index.js.map +1 -0
- package/lib/module/native-stack/navigators/createNativeStackNavigator.js +72 -0
- package/lib/module/native-stack/navigators/createNativeStackNavigator.js.map +1 -0
- package/lib/module/native-stack/types.js +2 -0
- package/lib/module/native-stack/types.js.map +1 -0
- package/lib/module/native-stack/utils/AnimatedHeaderHeightContext.js +4 -0
- package/lib/module/native-stack/utils/AnimatedHeaderHeightContext.js.map +1 -0
- package/lib/module/native-stack/utils/HeaderHeightContext.js +4 -0
- package/lib/module/native-stack/utils/HeaderHeightContext.js.map +1 -0
- package/lib/module/native-stack/utils/SafeAreaProviderCompat.js +68 -0
- package/lib/module/native-stack/utils/SafeAreaProviderCompat.js.map +1 -0
- package/lib/module/native-stack/utils/getDefaultHeaderHeight.js +29 -0
- package/lib/module/native-stack/utils/getDefaultHeaderHeight.js.map +1 -0
- package/lib/module/native-stack/utils/useAnimatedHeaderHeight.js +10 -0
- package/lib/module/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -0
- package/lib/module/native-stack/utils/useBackPressSubscription.js +47 -0
- package/lib/module/native-stack/utils/useBackPressSubscription.js.map +1 -0
- package/lib/module/native-stack/utils/useHeaderHeight.js +10 -0
- package/lib/module/native-stack/utils/useHeaderHeight.js.map +1 -0
- package/lib/module/native-stack/views/FontProcessor.js +13 -0
- package/lib/module/native-stack/views/FontProcessor.js.map +1 -0
- package/lib/module/native-stack/views/HeaderConfig.js +132 -0
- package/lib/module/native-stack/views/HeaderConfig.js.map +1 -0
- package/lib/module/native-stack/views/NativeStackView.js +355 -0
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -0
- package/lib/module/reanimated/ReanimatedHeaderHeightContext.js +5 -0
- package/lib/module/reanimated/ReanimatedHeaderHeightContext.js.map +1 -0
- package/lib/module/reanimated/ReanimatedNativeStackScreen.js +97 -0
- package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
- package/lib/module/reanimated/ReanimatedScreen.js +17 -0
- package/lib/module/reanimated/ReanimatedScreen.js.map +1 -0
- package/lib/module/reanimated/ReanimatedScreenProvider.js +40 -0
- package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -0
- package/lib/module/reanimated/ReanimatedTransitionProgressContext.js +5 -0
- package/lib/module/reanimated/ReanimatedTransitionProgressContext.js.map +1 -0
- package/lib/module/reanimated/index.js +4 -0
- package/lib/module/reanimated/index.js.map +1 -0
- package/lib/module/reanimated/useReanimatedHeaderHeight.js +10 -0
- package/lib/module/reanimated/useReanimatedHeaderHeight.js.map +1 -0
- package/lib/module/reanimated/useReanimatedTransitionProgress.js +10 -0
- package/lib/module/reanimated/useReanimatedTransitionProgress.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/useTransitionProgress.js +10 -0
- package/lib/module/useTransitionProgress.js.map +1 -0
- package/lib/module/utils.js +14 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/TransitionProgressContext.d.ts +9 -0
- package/lib/typescript/fabric/FullWindowOverlayNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/ScreenContainerNativeComponent.d.ts +5 -0
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts +66 -0
- package/lib/typescript/fabric/ScreenNavigationContainerNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +33 -0
- package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts +10 -0
- package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts +8 -0
- package/lib/typescript/fabric/SearchBarNativeComponent.d.ts +49 -0
- package/lib/typescript/index.d.ts +33 -0
- package/lib/typescript/index.native.d.ts +2 -0
- package/lib/typescript/native-stack/index.d.ts +19 -0
- package/lib/typescript/native-stack/navigators/createNativeStackNavigator.d.ts +6 -0
- package/lib/typescript/native-stack/types.d.ts +438 -0
- package/lib/typescript/native-stack/utils/AnimatedHeaderHeightContext.d.ts +4 -0
- package/lib/typescript/native-stack/utils/HeaderHeightContext.d.ts +3 -0
- package/lib/typescript/native-stack/utils/SafeAreaProviderCompat.d.ts +11 -0
- package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts +7 -0
- package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts +1 -0
- package/lib/typescript/native-stack/utils/useBackPressSubscription.d.ts +16 -0
- package/lib/typescript/native-stack/utils/useHeaderHeight.d.ts +1 -0
- package/lib/typescript/native-stack/views/FontProcessor.d.ts +1 -0
- package/lib/typescript/native-stack/views/HeaderConfig.d.ts +8 -0
- package/lib/typescript/native-stack/views/NativeStackView.d.ts +10 -0
- package/lib/typescript/reanimated/ReanimatedHeaderHeightContext.d.ts +4 -0
- package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +5 -0
- package/lib/typescript/reanimated/ReanimatedScreen.d.ts +5 -0
- package/lib/typescript/reanimated/ReanimatedScreenProvider.d.ts +2 -0
- package/lib/typescript/reanimated/ReanimatedTransitionProgressContext.d.ts +9 -0
- package/lib/typescript/reanimated/index.d.ts +3 -0
- package/lib/typescript/reanimated/useReanimatedHeaderHeight.d.ts +3 -0
- package/lib/typescript/reanimated/useReanimatedTransitionProgress.d.ts +11 -0
- package/lib/typescript/types.d.ts +612 -0
- package/lib/typescript/useTransitionProgress.d.ts +5 -0
- package/lib/typescript/utils.d.ts +3 -0
- package/native-stack/README.md +814 -0
- package/native-stack/package.json +6 -0
- package/package.json +1 -0
- package/react-native.config.js +42 -0
- package/reanimated/package.json +6 -0
- package/src/TransitionProgressContext.tsx +12 -0
- package/src/fabric/FullWindowOverlayNativeComponent.ts +7 -0
- package/src/fabric/ScreenContainerNativeComponent.ts +28 -0
- package/src/fabric/ScreenNativeComponent.ts +158 -0
- package/src/fabric/ScreenNavigationContainerNativeComponent.ts +10 -0
- package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +61 -0
- package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +22 -0
- package/src/fabric/ScreenStackNativeComponent.ts +33 -0
- package/src/fabric/SearchBarNativeComponent.ts +79 -0
- package/src/index.native.tsx +599 -0
- package/src/index.tsx +119 -0
- package/src/native-stack/index.tsx +27 -0
- package/src/native-stack/navigators/createNativeStackNavigator.tsx +107 -0
- package/src/native-stack/types.tsx +486 -0
- package/src/native-stack/utils/AnimatedHeaderHeightContext.tsx +8 -0
- package/src/native-stack/utils/HeaderHeightContext.tsx +5 -0
- package/src/native-stack/utils/SafeAreaProviderCompat.tsx +78 -0
- package/src/native-stack/utils/getDefaultHeaderHeight.tsx +41 -0
- package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +15 -0
- package/src/native-stack/utils/useBackPressSubscription.tsx +66 -0
- package/src/native-stack/utils/useHeaderHeight.tsx +15 -0
- package/src/native-stack/views/FontProcessor.tsx +14 -0
- package/src/native-stack/views/HeaderConfig.tsx +187 -0
- package/src/native-stack/views/NativeStackView.tsx +466 -0
- package/src/reanimated/ReanimatedHeaderHeightContext.tsx +7 -0
- package/src/reanimated/ReanimatedNativeStackScreen.tsx +130 -0
- package/src/reanimated/ReanimatedScreen.tsx +25 -0
- package/src/reanimated/ReanimatedScreenProvider.tsx +42 -0
- package/src/reanimated/ReanimatedTransitionProgressContext.tsx +13 -0
- package/src/reanimated/index.tsx +3 -0
- package/src/reanimated/useReanimatedHeaderHeight.tsx +14 -0
- package/src/reanimated/useReanimatedTransitionProgress.tsx +14 -0
- package/src/types.tsx +699 -0
- package/src/useTransitionProgress.tsx +15 -0
- package/src/utils.ts +18 -0
- package/windows/README.md +25 -0
- package/windows/RNScreens/PropertySheet.props +16 -0
- package/windows/RNScreens/RNScreens.cpp +66 -0
- package/windows/RNScreens/RNScreens.def +3 -0
- package/windows/RNScreens/RNScreens.h +41 -0
- package/windows/RNScreens/RNScreens.idl +8 -0
- package/windows/RNScreens/RNScreens.vcxproj +187 -0
- package/windows/RNScreens/RNScreens.vcxproj.filters +52 -0
- package/windows/RNScreens/ReactPackageProvider.cpp +30 -0
- package/windows/RNScreens/ReactPackageProvider.h +17 -0
- package/windows/RNScreens/ReactPackageProvider.idl +9 -0
- package/windows/RNScreens/Screen.cpp +122 -0
- package/windows/RNScreens/Screen.h +64 -0
- package/windows/RNScreens/ScreenContainer.cpp +49 -0
- package/windows/RNScreens/ScreenContainer.h +23 -0
- package/windows/RNScreens/ScreenContainerViewManager.cpp +133 -0
- package/windows/RNScreens/ScreenContainerViewManager.h +78 -0
- package/windows/RNScreens/ScreenStack.cpp +65 -0
- package/windows/RNScreens/ScreenStack.h +23 -0
- package/windows/RNScreens/ScreenStackHeaderConfig.cpp +19 -0
- package/windows/RNScreens/ScreenStackHeaderConfig.h +14 -0
- package/windows/RNScreens/ScreenStackHeaderConfigViewManager.cpp +89 -0
- package/windows/RNScreens/ScreenStackHeaderConfigViewManager.h +62 -0
- package/windows/RNScreens/ScreenStackViewManager.cpp +132 -0
- package/windows/RNScreens/ScreenStackViewManager.h +78 -0
- package/windows/RNScreens/ScreenViewManager.cpp +154 -0
- package/windows/RNScreens/ScreenViewManager.h +78 -0
- package/windows/RNScreens/packages.config +4 -0
- package/windows/RNScreens/pch.cpp +1 -0
- package/windows/RNScreens/pch.h +9 -0
- package/windows/RNScreens62.sln +254 -0
- package/windows/RNScreens63.sln +225 -0
- package/windows/RNScreens65.sln +144 -0
package/ios/RNSScreen.mm
ADDED
|
@@ -0,0 +1,1599 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
#import "RNSScreen.h"
|
|
4
|
+
#import "RNSScreenContainer.h"
|
|
5
|
+
#import "RNSScreenWindowTraits.h"
|
|
6
|
+
|
|
7
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
8
|
+
#import <React/RCTConversions.h>
|
|
9
|
+
#import <React/RCTFabricComponentsPlugins.h>
|
|
10
|
+
#import <React/RCTRootComponentView.h>
|
|
11
|
+
#import <React/RCTSurfaceTouchHandler.h>
|
|
12
|
+
#import <react/renderer/components/rnscreens/EventEmitters.h>
|
|
13
|
+
#import <react/renderer/components/rnscreens/Props.h>
|
|
14
|
+
#import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
|
|
15
|
+
#import <rnscreens/RNSScreenComponentDescriptor.h>
|
|
16
|
+
#import "RNSConvert.h"
|
|
17
|
+
#import "RNSHeaderHeightChangeEvent.h"
|
|
18
|
+
#import "RNSScreenViewEvent.h"
|
|
19
|
+
#else
|
|
20
|
+
#import <React/RCTTouchHandler.h>
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
#import <React/RCTShadowView.h>
|
|
24
|
+
#import <React/RCTUIManager.h>
|
|
25
|
+
#import "RNSScreenStack.h"
|
|
26
|
+
#import "RNSScreenStackHeaderConfig.h"
|
|
27
|
+
|
|
28
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
29
|
+
namespace react = facebook::react;
|
|
30
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
31
|
+
|
|
32
|
+
@interface RNSScreenView ()
|
|
33
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
34
|
+
<RCTRNSScreenViewProtocol, UIAdaptivePresentationControllerDelegate>
|
|
35
|
+
#else
|
|
36
|
+
<UIAdaptivePresentationControllerDelegate, RCTInvalidating>
|
|
37
|
+
#endif
|
|
38
|
+
@end
|
|
39
|
+
|
|
40
|
+
@implementation RNSScreenView {
|
|
41
|
+
__weak RCTBridge *_bridge;
|
|
42
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
43
|
+
RCTSurfaceTouchHandler *_touchHandler;
|
|
44
|
+
react::RNSScreenShadowNode::ConcreteState::Shared _state;
|
|
45
|
+
// on fabric, they are not available by default so we need them exposed here too
|
|
46
|
+
NSMutableArray<UIView *> *_reactSubviews;
|
|
47
|
+
#else
|
|
48
|
+
RCTTouchHandler *_touchHandler;
|
|
49
|
+
CGRect _reactFrame;
|
|
50
|
+
#endif
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
54
|
+
- (instancetype)initWithFrame:(CGRect)frame
|
|
55
|
+
{
|
|
56
|
+
if (self = [super initWithFrame:frame]) {
|
|
57
|
+
static const auto defaultProps = std::make_shared<const react::RNSScreenProps>();
|
|
58
|
+
_props = defaultProps;
|
|
59
|
+
_reactSubviews = [NSMutableArray new];
|
|
60
|
+
[self initCommonProps];
|
|
61
|
+
}
|
|
62
|
+
return self;
|
|
63
|
+
}
|
|
64
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
65
|
+
|
|
66
|
+
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
|
67
|
+
{
|
|
68
|
+
if (self = [super init]) {
|
|
69
|
+
_bridge = bridge;
|
|
70
|
+
[self initCommonProps];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return self;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
- (void)initCommonProps
|
|
77
|
+
{
|
|
78
|
+
_controller = [[RNSScreen alloc] initWithView:self];
|
|
79
|
+
_stackPresentation = RNSScreenStackPresentationPush;
|
|
80
|
+
_stackAnimation = RNSScreenStackAnimationDefault;
|
|
81
|
+
_gestureEnabled = YES;
|
|
82
|
+
_replaceAnimation = RNSScreenReplaceAnimationPop;
|
|
83
|
+
_dismissed = NO;
|
|
84
|
+
_hasStatusBarStyleSet = NO;
|
|
85
|
+
_hasStatusBarAnimationSet = NO;
|
|
86
|
+
_hasStatusBarHiddenSet = NO;
|
|
87
|
+
_hasOrientationSet = NO;
|
|
88
|
+
_hasHomeIndicatorHiddenSet = NO;
|
|
89
|
+
#if !TARGET_OS_TV
|
|
90
|
+
_sheetExpandsWhenScrolledToEdge = YES;
|
|
91
|
+
#endif // !TARGET_OS_TV
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
- (UIViewController *)reactViewController
|
|
95
|
+
{
|
|
96
|
+
return _controller;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
100
|
+
- (NSArray<UIView *> *)reactSubviews
|
|
101
|
+
{
|
|
102
|
+
return _reactSubviews;
|
|
103
|
+
}
|
|
104
|
+
#endif
|
|
105
|
+
|
|
106
|
+
- (void)updateBounds
|
|
107
|
+
{
|
|
108
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
109
|
+
if (_state != nullptr) {
|
|
110
|
+
auto newState = react::RNSScreenState{RCTSizeFromCGSize(self.bounds.size)};
|
|
111
|
+
_state->updateState(std::move(newState));
|
|
112
|
+
UINavigationController *navctr = _controller.navigationController;
|
|
113
|
+
[navctr.view setNeedsLayout];
|
|
114
|
+
}
|
|
115
|
+
#else
|
|
116
|
+
[_bridge.uiManager setSize:self.bounds.size forView:self];
|
|
117
|
+
#endif
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
- (void)setStackPresentation:(RNSScreenStackPresentation)stackPresentation
|
|
121
|
+
{
|
|
122
|
+
switch (stackPresentation) {
|
|
123
|
+
case RNSScreenStackPresentationModal:
|
|
124
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
|
|
125
|
+
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
|
|
126
|
+
if (@available(iOS 13.0, tvOS 13.0, *)) {
|
|
127
|
+
_controller.modalPresentationStyle = UIModalPresentationAutomatic;
|
|
128
|
+
} else {
|
|
129
|
+
_controller.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
130
|
+
}
|
|
131
|
+
#else
|
|
132
|
+
_controller.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
133
|
+
#endif
|
|
134
|
+
break;
|
|
135
|
+
case RNSScreenStackPresentationFullScreenModal:
|
|
136
|
+
_controller.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
137
|
+
break;
|
|
138
|
+
#if !TARGET_OS_TV
|
|
139
|
+
case RNSScreenStackPresentationFormSheet:
|
|
140
|
+
_controller.modalPresentationStyle = UIModalPresentationFormSheet;
|
|
141
|
+
break;
|
|
142
|
+
#endif
|
|
143
|
+
case RNSScreenStackPresentationTransparentModal:
|
|
144
|
+
_controller.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
|
145
|
+
break;
|
|
146
|
+
case RNSScreenStackPresentationContainedModal:
|
|
147
|
+
_controller.modalPresentationStyle = UIModalPresentationCurrentContext;
|
|
148
|
+
break;
|
|
149
|
+
case RNSScreenStackPresentationContainedTransparentModal:
|
|
150
|
+
_controller.modalPresentationStyle = UIModalPresentationOverCurrentContext;
|
|
151
|
+
break;
|
|
152
|
+
case RNSScreenStackPresentationPush:
|
|
153
|
+
// ignored, we only need to keep in mind not to set presentation delegate
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// There is a bug in UIKit which causes retain loop when presentationController is accessed for a
|
|
158
|
+
// controller that is not going to be presented modally. We therefore need to avoid setting the
|
|
159
|
+
// delegate for screens presented using push. This also means that when controller is updated from
|
|
160
|
+
// modal to push type, this may cause memory leak, we warn about that as well.
|
|
161
|
+
if (stackPresentation != RNSScreenStackPresentationPush) {
|
|
162
|
+
// `modalPresentationStyle` must be set before accessing `presentationController`
|
|
163
|
+
// otherwise a default controller will be created and cannot be changed after.
|
|
164
|
+
// Documented here:
|
|
165
|
+
// https://developer.apple.com/documentation/uikit/uiviewcontroller/1621426-presentationcontroller?language=objc
|
|
166
|
+
_controller.presentationController.delegate = self;
|
|
167
|
+
} else if (_stackPresentation != RNSScreenStackPresentationPush) {
|
|
168
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
169
|
+
// TODO: on Fabric, same controllers can be used as modals and then recycled and used a push which would result in
|
|
170
|
+
// this error. It would be good to check if it doesn't leak in such case.
|
|
171
|
+
#else
|
|
172
|
+
RCTLogError(
|
|
173
|
+
@"Screen presentation updated from modal to push, this may likely result in a screen object leakage. If you need to change presentation style create a new screen object instead");
|
|
174
|
+
#endif
|
|
175
|
+
}
|
|
176
|
+
_stackPresentation = stackPresentation;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
- (void)setStackAnimation:(RNSScreenStackAnimation)stackAnimation
|
|
180
|
+
{
|
|
181
|
+
_stackAnimation = stackAnimation;
|
|
182
|
+
|
|
183
|
+
switch (stackAnimation) {
|
|
184
|
+
case RNSScreenStackAnimationFade:
|
|
185
|
+
_controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
|
|
186
|
+
break;
|
|
187
|
+
#if !TARGET_OS_TV
|
|
188
|
+
case RNSScreenStackAnimationFlip:
|
|
189
|
+
_controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
|
|
190
|
+
break;
|
|
191
|
+
#endif
|
|
192
|
+
case RNSScreenStackAnimationNone:
|
|
193
|
+
case RNSScreenStackAnimationDefault:
|
|
194
|
+
case RNSScreenStackAnimationSimplePush:
|
|
195
|
+
case RNSScreenStackAnimationSlideFromBottom:
|
|
196
|
+
case RNSScreenStackAnimationFadeFromBottom:
|
|
197
|
+
// Default
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
- (void)setGestureEnabled:(BOOL)gestureEnabled
|
|
203
|
+
{
|
|
204
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
|
|
205
|
+
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
|
|
206
|
+
if (@available(iOS 13.0, tvOS 13.0, *)) {
|
|
207
|
+
_controller.modalInPresentation = !gestureEnabled;
|
|
208
|
+
}
|
|
209
|
+
#endif
|
|
210
|
+
|
|
211
|
+
_gestureEnabled = gestureEnabled;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
- (void)setReplaceAnimation:(RNSScreenReplaceAnimation)replaceAnimation
|
|
215
|
+
{
|
|
216
|
+
_replaceAnimation = replaceAnimation;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Nil will be provided when activityState is set as an animated value and we change
|
|
220
|
+
// it from JS to be a plain value (non animated).
|
|
221
|
+
// In case when nil is received, we want to ignore such value and not make
|
|
222
|
+
// any updates as the actual non-nil value will follow immediately.
|
|
223
|
+
- (void)setActivityStateOrNil:(NSNumber *)activityStateOrNil
|
|
224
|
+
{
|
|
225
|
+
int activityState = [activityStateOrNil intValue];
|
|
226
|
+
if (activityStateOrNil != nil && activityState != -1 && activityState != _activityState) {
|
|
227
|
+
_activityState = activityState;
|
|
228
|
+
[_reactSuperview markChildUpdated];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
#if !TARGET_OS_TV
|
|
233
|
+
- (void)setStatusBarStyle:(RNSStatusBarStyle)statusBarStyle
|
|
234
|
+
{
|
|
235
|
+
_hasStatusBarStyleSet = YES;
|
|
236
|
+
_statusBarStyle = statusBarStyle;
|
|
237
|
+
[RNSScreenWindowTraits assertViewControllerBasedStatusBarAppearenceSet];
|
|
238
|
+
[RNSScreenWindowTraits updateStatusBarAppearance];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
- (void)setStatusBarAnimation:(UIStatusBarAnimation)statusBarAnimation
|
|
242
|
+
{
|
|
243
|
+
_hasStatusBarAnimationSet = YES;
|
|
244
|
+
_statusBarAnimation = statusBarAnimation;
|
|
245
|
+
[RNSScreenWindowTraits assertViewControllerBasedStatusBarAppearenceSet];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
- (void)setStatusBarHidden:(BOOL)statusBarHidden
|
|
249
|
+
{
|
|
250
|
+
_hasStatusBarHiddenSet = YES;
|
|
251
|
+
_statusBarHidden = statusBarHidden;
|
|
252
|
+
[RNSScreenWindowTraits assertViewControllerBasedStatusBarAppearenceSet];
|
|
253
|
+
[RNSScreenWindowTraits updateStatusBarAppearance];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
- (void)setScreenOrientation:(UIInterfaceOrientationMask)screenOrientation
|
|
257
|
+
{
|
|
258
|
+
_hasOrientationSet = YES;
|
|
259
|
+
_screenOrientation = screenOrientation;
|
|
260
|
+
[RNSScreenWindowTraits enforceDesiredDeviceOrientation];
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
- (void)setHomeIndicatorHidden:(BOOL)homeIndicatorHidden
|
|
264
|
+
{
|
|
265
|
+
_hasHomeIndicatorHiddenSet = YES;
|
|
266
|
+
_homeIndicatorHidden = homeIndicatorHidden;
|
|
267
|
+
[RNSScreenWindowTraits updateHomeIndicatorAutoHidden];
|
|
268
|
+
}
|
|
269
|
+
#endif
|
|
270
|
+
|
|
271
|
+
- (UIView *)reactSuperview
|
|
272
|
+
{
|
|
273
|
+
return _reactSuperview;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
- (void)addSubview:(UIView *)view
|
|
277
|
+
{
|
|
278
|
+
if (![view isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
|
279
|
+
[super addSubview:view];
|
|
280
|
+
} else {
|
|
281
|
+
((RNSScreenStackHeaderConfig *)view).screenView = self;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
- (void)notifyDismissedWithCount:(int)dismissCount
|
|
286
|
+
{
|
|
287
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
288
|
+
// If screen is already unmounted then there will be no event emitter
|
|
289
|
+
// it will be cleaned in prepareForRecycle
|
|
290
|
+
if (_eventEmitter != nullptr) {
|
|
291
|
+
std::dynamic_pointer_cast<const react::RNSScreenEventEmitter>(_eventEmitter)
|
|
292
|
+
->onDismissed(react::RNSScreenEventEmitter::OnDismissed{.dismissCount = dismissCount});
|
|
293
|
+
}
|
|
294
|
+
#else
|
|
295
|
+
// TODO: hopefully problems connected to dismissed prop are only the case on paper
|
|
296
|
+
_dismissed = YES;
|
|
297
|
+
if (self.onDismissed) {
|
|
298
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
299
|
+
if (self.onDismissed) {
|
|
300
|
+
self.onDismissed(@{@"dismissCount" : @(dismissCount)});
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
#endif
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
- (void)notifyDismissCancelledWithDismissCount:(int)dismissCount
|
|
308
|
+
{
|
|
309
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
310
|
+
// If screen is already unmounted then there will be no event emitter
|
|
311
|
+
// it will be cleaned in prepareForRecycle
|
|
312
|
+
if (_eventEmitter != nullptr) {
|
|
313
|
+
std::dynamic_pointer_cast<const react::RNSScreenEventEmitter>(_eventEmitter)
|
|
314
|
+
->onNativeDismissCancelled(
|
|
315
|
+
react::RNSScreenEventEmitter::OnNativeDismissCancelled{.dismissCount = dismissCount});
|
|
316
|
+
}
|
|
317
|
+
#else
|
|
318
|
+
if (self.onNativeDismissCancelled) {
|
|
319
|
+
self.onNativeDismissCancelled(@{@"dismissCount" : @(dismissCount)});
|
|
320
|
+
}
|
|
321
|
+
#endif
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
- (void)notifyWillAppear
|
|
325
|
+
{
|
|
326
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
327
|
+
// If screen is already unmounted then there will be no event emitter
|
|
328
|
+
// it will be cleaned in prepareForRecycle
|
|
329
|
+
if (_eventEmitter != nullptr) {
|
|
330
|
+
std::dynamic_pointer_cast<const react::RNSScreenEventEmitter>(_eventEmitter)
|
|
331
|
+
->onWillAppear(react::RNSScreenEventEmitter::OnWillAppear{});
|
|
332
|
+
}
|
|
333
|
+
[self updateLayoutMetrics:_newLayoutMetrics oldLayoutMetrics:_oldLayoutMetrics];
|
|
334
|
+
#else
|
|
335
|
+
if (self.onWillAppear) {
|
|
336
|
+
self.onWillAppear(nil);
|
|
337
|
+
}
|
|
338
|
+
// we do it here too because at this moment the `parentViewController` is already not nil,
|
|
339
|
+
// so if the parent is not UINavCtr, the frame will be updated to the correct one.
|
|
340
|
+
[self reactSetFrame:_reactFrame];
|
|
341
|
+
#endif
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
- (void)notifyWillDisappear
|
|
345
|
+
{
|
|
346
|
+
if (_hideKeyboardOnSwipe) {
|
|
347
|
+
[self endEditing:YES];
|
|
348
|
+
}
|
|
349
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
350
|
+
// If screen is already unmounted then there will be no event emitter
|
|
351
|
+
// it will be cleaned in prepareForRecycle
|
|
352
|
+
if (_eventEmitter != nullptr) {
|
|
353
|
+
std::dynamic_pointer_cast<const react::RNSScreenEventEmitter>(_eventEmitter)
|
|
354
|
+
->onWillDisappear(react::RNSScreenEventEmitter::OnWillDisappear{});
|
|
355
|
+
}
|
|
356
|
+
#else
|
|
357
|
+
if (self.onWillDisappear) {
|
|
358
|
+
self.onWillDisappear(nil);
|
|
359
|
+
}
|
|
360
|
+
#endif
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
- (void)notifyAppear
|
|
364
|
+
{
|
|
365
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
366
|
+
// If screen is already unmounted then there will be no event emitter
|
|
367
|
+
// it will be cleaned in prepareForRecycle
|
|
368
|
+
if (_eventEmitter != nullptr) {
|
|
369
|
+
std::dynamic_pointer_cast<const react::RNSScreenEventEmitter>(_eventEmitter)
|
|
370
|
+
->onAppear(react::RNSScreenEventEmitter::OnAppear{});
|
|
371
|
+
}
|
|
372
|
+
#else
|
|
373
|
+
if (self.onAppear) {
|
|
374
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
375
|
+
if (self.onAppear) {
|
|
376
|
+
self.onAppear(nil);
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
#endif
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
- (void)notifyDisappear
|
|
384
|
+
{
|
|
385
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
386
|
+
// If screen is already unmounted then there will be no event emitter
|
|
387
|
+
// it will be cleaned in prepareForRecycle
|
|
388
|
+
if (_eventEmitter != nullptr) {
|
|
389
|
+
std::dynamic_pointer_cast<const react::RNSScreenEventEmitter>(_eventEmitter)
|
|
390
|
+
->onDisappear(react::RNSScreenEventEmitter::OnDisappear{});
|
|
391
|
+
}
|
|
392
|
+
#else
|
|
393
|
+
if (self.onDisappear) {
|
|
394
|
+
self.onDisappear(nil);
|
|
395
|
+
}
|
|
396
|
+
#endif
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
- (void)notifyHeaderHeightChange:(double)headerHeight
|
|
400
|
+
{
|
|
401
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
402
|
+
if (_eventEmitter != nullptr) {
|
|
403
|
+
std::dynamic_pointer_cast<const facebook::react::RNSScreenEventEmitter>(_eventEmitter)
|
|
404
|
+
->onHeaderHeightChange(
|
|
405
|
+
facebook::react::RNSScreenEventEmitter::OnHeaderHeightChange{.headerHeight = headerHeight});
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
RNSHeaderHeightChangeEvent *event =
|
|
409
|
+
[[RNSHeaderHeightChangeEvent alloc] initWithEventName:@"onHeaderHeightChange"
|
|
410
|
+
reactTag:[NSNumber numberWithInt:self.tag]
|
|
411
|
+
headerHeight:headerHeight];
|
|
412
|
+
[[RCTBridge currentBridge].eventDispatcher sendEvent:event];
|
|
413
|
+
#else
|
|
414
|
+
if (self.onHeaderHeightChange) {
|
|
415
|
+
self.onHeaderHeightChange(@{
|
|
416
|
+
@"headerHeight" : @(headerHeight),
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
#endif
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
- (void)notifyGestureCancel
|
|
423
|
+
{
|
|
424
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
425
|
+
if (_eventEmitter != nullptr) {
|
|
426
|
+
std::dynamic_pointer_cast<const react::RNSScreenEventEmitter>(_eventEmitter)
|
|
427
|
+
->onGestureCancel(react::RNSScreenEventEmitter::OnGestureCancel{});
|
|
428
|
+
}
|
|
429
|
+
#else
|
|
430
|
+
if (self.onGestureCancel) {
|
|
431
|
+
self.onGestureCancel(nil);
|
|
432
|
+
}
|
|
433
|
+
#endif
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
- (BOOL)isMountedUnderScreenOrReactRoot
|
|
437
|
+
{
|
|
438
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
439
|
+
#define RNS_EXPECTED_VIEW RCTRootComponentView
|
|
440
|
+
#else
|
|
441
|
+
#define RNS_EXPECTED_VIEW RCTRootView
|
|
442
|
+
#endif
|
|
443
|
+
for (UIView *parent = self.superview; parent != nil; parent = parent.superview) {
|
|
444
|
+
if ([parent isKindOfClass:[RNS_EXPECTED_VIEW class]] || [parent isKindOfClass:[RNSScreenView class]]) {
|
|
445
|
+
return YES;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return NO;
|
|
449
|
+
#undef RNS_EXPECTED_VIEW
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
- (void)didMoveToWindow
|
|
453
|
+
{
|
|
454
|
+
// For RN touches to work we need to instantiate and connect RCTTouchHandler. This only applies
|
|
455
|
+
// for screens that aren't mounted under RCTRootView e.g., modals that are mounted directly to
|
|
456
|
+
// root application window.
|
|
457
|
+
if (self.window != nil && ![self isMountedUnderScreenOrReactRoot]) {
|
|
458
|
+
if (_touchHandler == nil) {
|
|
459
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
460
|
+
_touchHandler = [RCTSurfaceTouchHandler new];
|
|
461
|
+
#else
|
|
462
|
+
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge];
|
|
463
|
+
#endif
|
|
464
|
+
}
|
|
465
|
+
[_touchHandler attachToView:self];
|
|
466
|
+
} else {
|
|
467
|
+
[_touchHandler detachFromView:self];
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
472
|
+
- (RCTSurfaceTouchHandler *)touchHandler
|
|
473
|
+
#else
|
|
474
|
+
- (RCTTouchHandler *)touchHandler
|
|
475
|
+
#endif
|
|
476
|
+
{
|
|
477
|
+
if (_touchHandler != nil) {
|
|
478
|
+
return _touchHandler;
|
|
479
|
+
}
|
|
480
|
+
UIView *parent = [self superview];
|
|
481
|
+
while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)])
|
|
482
|
+
parent = parent.superview;
|
|
483
|
+
if (parent != nil) {
|
|
484
|
+
return [parent performSelector:@selector(touchHandler)];
|
|
485
|
+
}
|
|
486
|
+
return nil;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
- (void)notifyFinishTransitioning
|
|
490
|
+
{
|
|
491
|
+
[_controller notifyFinishTransitioning];
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
- (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward
|
|
495
|
+
{
|
|
496
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
497
|
+
if (_eventEmitter != nullptr) {
|
|
498
|
+
std::dynamic_pointer_cast<const react::RNSScreenEventEmitter>(_eventEmitter)
|
|
499
|
+
->onTransitionProgress(react::RNSScreenEventEmitter::OnTransitionProgress{
|
|
500
|
+
.progress = progress, .closing = closing ? 1 : 0, .goingForward = goingForward ? 1 : 0});
|
|
501
|
+
}
|
|
502
|
+
RNSScreenViewEvent *event = [[RNSScreenViewEvent alloc] initWithEventName:@"onTransitionProgress"
|
|
503
|
+
reactTag:[NSNumber numberWithInt:self.tag]
|
|
504
|
+
progress:progress
|
|
505
|
+
closing:closing
|
|
506
|
+
goingForward:goingForward];
|
|
507
|
+
[[RCTBridge currentBridge].eventDispatcher sendEvent:event];
|
|
508
|
+
#else
|
|
509
|
+
if (self.onTransitionProgress) {
|
|
510
|
+
self.onTransitionProgress(@{
|
|
511
|
+
@"progress" : @(progress),
|
|
512
|
+
@"closing" : @(closing ? 1 : 0),
|
|
513
|
+
@"goingForward" : @(goingForward ? 1 : 0),
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
#endif
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
- (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController
|
|
520
|
+
{
|
|
521
|
+
// We need to call both "cancel" and "reset" here because RN's gesture recognizer
|
|
522
|
+
// does not handle the scenario when it gets cancelled by other top
|
|
523
|
+
// level gesture recognizer. In this case by the modal dismiss gesture.
|
|
524
|
+
// Because of that, at the moment when this method gets called the React's
|
|
525
|
+
// gesture recognizer is already in FAILED state but cancel events never gets
|
|
526
|
+
// send to JS. Calling "reset" forces RCTTouchHanler to dispatch cancel event.
|
|
527
|
+
// To test this behavior one need to open a dismissable modal and start
|
|
528
|
+
// pulling down starting at some touchable item. Without "reset" the touchable
|
|
529
|
+
// will never go back from highlighted state even when the modal start sliding
|
|
530
|
+
// down.
|
|
531
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
532
|
+
[_touchHandler setEnabled:NO];
|
|
533
|
+
[_touchHandler setEnabled:YES];
|
|
534
|
+
#else
|
|
535
|
+
[_touchHandler cancel];
|
|
536
|
+
#endif
|
|
537
|
+
[_touchHandler reset];
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
- (BOOL)presentationControllerShouldDismiss:(UIPresentationController *)presentationController
|
|
541
|
+
{
|
|
542
|
+
if (_preventNativeDismiss) {
|
|
543
|
+
[self notifyDismissCancelledWithDismissCount:1];
|
|
544
|
+
return NO;
|
|
545
|
+
}
|
|
546
|
+
return _gestureEnabled;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController
|
|
550
|
+
{
|
|
551
|
+
if ([_reactSuperview respondsToSelector:@selector(presentationControllerDidDismiss:)]) {
|
|
552
|
+
[_reactSuperview performSelector:@selector(presentationControllerDidDismiss:) withObject:presentationController];
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
- (RNSScreenStackHeaderConfig *_Nullable)findHeaderConfig
|
|
557
|
+
{
|
|
558
|
+
for (UIView *view in self.reactSubviews) {
|
|
559
|
+
if ([view isKindOfClass:RNSScreenStackHeaderConfig.class]) {
|
|
560
|
+
return (RNSScreenStackHeaderConfig *)view;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return nil;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
- (BOOL)isModal
|
|
567
|
+
{
|
|
568
|
+
return self.stackPresentation != RNSScreenStackPresentationPush;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
- (BOOL)isPresentedAsNativeModal
|
|
572
|
+
{
|
|
573
|
+
return self.controller.parentViewController == nil && self.controller.presentingViewController != nil;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
- (BOOL)isFullscreenModal
|
|
577
|
+
{
|
|
578
|
+
switch (self.controller.modalPresentationStyle) {
|
|
579
|
+
case UIModalPresentationFullScreen:
|
|
580
|
+
case UIModalPresentationCurrentContext:
|
|
581
|
+
case UIModalPresentationOverCurrentContext:
|
|
582
|
+
return YES;
|
|
583
|
+
default:
|
|
584
|
+
return NO;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
- (BOOL)isTransparentModal
|
|
589
|
+
{
|
|
590
|
+
return self.controller.modalPresentationStyle == UIModalPresentationOverFullScreen ||
|
|
591
|
+
self.controller.modalPresentationStyle == UIModalPresentationOverCurrentContext;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
#if !TARGET_OS_TV
|
|
595
|
+
/**
|
|
596
|
+
* Updates settings for sheet presentation controller.
|
|
597
|
+
* Note that this method should not be called inside `stackPresentation` setter, because on Paper we don't have
|
|
598
|
+
* guarantee that values of all related props had been updated earlier.
|
|
599
|
+
*/
|
|
600
|
+
- (void)updatePresentationStyle
|
|
601
|
+
{
|
|
602
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_15_0) && \
|
|
603
|
+
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0
|
|
604
|
+
if (@available(iOS 15.0, *)) {
|
|
605
|
+
UISheetPresentationController *sheet = _controller.sheetPresentationController;
|
|
606
|
+
if (_stackPresentation == RNSScreenStackPresentationFormSheet && sheet != nil) {
|
|
607
|
+
sheet.prefersScrollingExpandsWhenScrolledToEdge = _sheetExpandsWhenScrolledToEdge;
|
|
608
|
+
sheet.prefersGrabberVisible = _sheetGrabberVisible;
|
|
609
|
+
sheet.preferredCornerRadius =
|
|
610
|
+
_sheetCornerRadius < 0 ? UISheetPresentationControllerAutomaticDimension : _sheetCornerRadius;
|
|
611
|
+
|
|
612
|
+
if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeMedium) {
|
|
613
|
+
sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium;
|
|
614
|
+
} else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeLarge) {
|
|
615
|
+
sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge;
|
|
616
|
+
} else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeAll) {
|
|
617
|
+
sheet.largestUndimmedDetentIdentifier = nil;
|
|
618
|
+
} else {
|
|
619
|
+
RCTLogError(@"Unhandled value of sheetLargestUndimmedDetent passed");
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
if (_sheetAllowedDetents == RNSScreenDetentTypeMedium) {
|
|
623
|
+
sheet.detents = @[ UISheetPresentationControllerDetent.mediumDetent ];
|
|
624
|
+
if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierMedium) {
|
|
625
|
+
[sheet animateChanges:^{
|
|
626
|
+
sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium;
|
|
627
|
+
}];
|
|
628
|
+
}
|
|
629
|
+
} else if (_sheetAllowedDetents == RNSScreenDetentTypeLarge) {
|
|
630
|
+
sheet.detents = @[ UISheetPresentationControllerDetent.largeDetent ];
|
|
631
|
+
if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierLarge) {
|
|
632
|
+
[sheet animateChanges:^{
|
|
633
|
+
sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge;
|
|
634
|
+
}];
|
|
635
|
+
}
|
|
636
|
+
} else if (_sheetAllowedDetents == RNSScreenDetentTypeAll) {
|
|
637
|
+
sheet.detents =
|
|
638
|
+
@[ UISheetPresentationControllerDetent.mediumDetent, UISheetPresentationControllerDetent.largeDetent ];
|
|
639
|
+
} else {
|
|
640
|
+
RCTLogError(@"Unhandled value of sheetAllowedDetents passed");
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
#endif // Check for max allowed iOS version
|
|
645
|
+
}
|
|
646
|
+
#endif // !TARGET_OS_TV
|
|
647
|
+
|
|
648
|
+
#pragma mark - Fabric specific
|
|
649
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
650
|
+
|
|
651
|
+
- (BOOL)hasHeaderConfig
|
|
652
|
+
{
|
|
653
|
+
return _config != nil;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
+ (react::ComponentDescriptorProvider)componentDescriptorProvider
|
|
657
|
+
{
|
|
658
|
+
return react::concreteComponentDescriptorProvider<react::RNSScreenComponentDescriptor>();
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
|
662
|
+
{
|
|
663
|
+
if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
|
664
|
+
_config = (RNSScreenStackHeaderConfig *)childComponentView;
|
|
665
|
+
_config.screenView = self;
|
|
666
|
+
}
|
|
667
|
+
[_reactSubviews insertObject:childComponentView atIndex:index];
|
|
668
|
+
[super mountChildComponentView:childComponentView index:index];
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
|
672
|
+
{
|
|
673
|
+
if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
|
674
|
+
_config = nil;
|
|
675
|
+
}
|
|
676
|
+
[_reactSubviews removeObject:childComponentView];
|
|
677
|
+
[super unmountChildComponentView:childComponentView index:index];
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
#pragma mark - RCTComponentViewProtocol
|
|
681
|
+
|
|
682
|
+
- (void)prepareForRecycle
|
|
683
|
+
{
|
|
684
|
+
[super prepareForRecycle];
|
|
685
|
+
// TODO: Make sure that there is no edge case when this should be uncommented
|
|
686
|
+
// _controller=nil;
|
|
687
|
+
_dismissed = NO;
|
|
688
|
+
_state.reset();
|
|
689
|
+
_touchHandler = nil;
|
|
690
|
+
|
|
691
|
+
// We set this prop to default value here to workaround view-recycling.
|
|
692
|
+
// Let's assume the view has had _stackPresentation == <some modal stack presentation> set
|
|
693
|
+
// before below line was executed. Then, when instantiated again (with the same modal presentation)
|
|
694
|
+
// updateProps:oldProps: method would be called and setter for stack presentation would not be called.
|
|
695
|
+
// This is crucial as in that setter we register `self.controller` as a delegate
|
|
696
|
+
// (UIAdaptivePresentationControllerDelegate) to presentation controller and this leads to buggy modal behaviour as we
|
|
697
|
+
// rely on UIAdaptivePresentationControllerDelegate callbacks. Restoring the default value and then comparing against
|
|
698
|
+
// it in updateProps:oldProps: allows for setter to be called, however if there was some additional logic to execute
|
|
699
|
+
// when stackPresentation is set to "push" the setter would not be triggered.
|
|
700
|
+
_stackPresentation = RNSScreenStackPresentationPush;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
- (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::Shared const &)oldProps
|
|
704
|
+
{
|
|
705
|
+
const auto &oldScreenProps = *std::static_pointer_cast<const react::RNSScreenProps>(_props);
|
|
706
|
+
const auto &newScreenProps = *std::static_pointer_cast<const react::RNSScreenProps>(props);
|
|
707
|
+
|
|
708
|
+
[self setFullScreenSwipeEnabled:newScreenProps.fullScreenSwipeEnabled];
|
|
709
|
+
|
|
710
|
+
[self setGestureEnabled:newScreenProps.gestureEnabled];
|
|
711
|
+
|
|
712
|
+
[self setTransitionDuration:[NSNumber numberWithInt:newScreenProps.transitionDuration]];
|
|
713
|
+
|
|
714
|
+
[self setHideKeyboardOnSwipe:newScreenProps.hideKeyboardOnSwipe];
|
|
715
|
+
|
|
716
|
+
[self setCustomAnimationOnSwipe:newScreenProps.customAnimationOnSwipe];
|
|
717
|
+
|
|
718
|
+
[self
|
|
719
|
+
setGestureResponseDistance:[RNSConvert
|
|
720
|
+
gestureResponseDistanceDictFromCppStruct:newScreenProps.gestureResponseDistance]];
|
|
721
|
+
|
|
722
|
+
[self setPreventNativeDismiss:newScreenProps.preventNativeDismiss];
|
|
723
|
+
|
|
724
|
+
[self setActivityStateOrNil:[NSNumber numberWithFloat:newScreenProps.activityState]];
|
|
725
|
+
|
|
726
|
+
[self setSwipeDirection:[RNSConvert RNSScreenSwipeDirectionFromCppEquivalent:newScreenProps.swipeDirection]];
|
|
727
|
+
|
|
728
|
+
#if !TARGET_OS_TV
|
|
729
|
+
if (newScreenProps.statusBarHidden != oldScreenProps.statusBarHidden) {
|
|
730
|
+
[self setStatusBarHidden:newScreenProps.statusBarHidden];
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
if (newScreenProps.statusBarStyle != oldScreenProps.statusBarStyle) {
|
|
734
|
+
[self setStatusBarStyle:[RCTConvert
|
|
735
|
+
RNSStatusBarStyle:RCTNSStringFromStringNilIfEmpty(newScreenProps.statusBarStyle)]];
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
if (newScreenProps.statusBarAnimation != oldScreenProps.statusBarAnimation) {
|
|
739
|
+
[self setStatusBarAnimation:[RCTConvert UIStatusBarAnimation:RCTNSStringFromStringNilIfEmpty(
|
|
740
|
+
newScreenProps.statusBarAnimation)]];
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
if (newScreenProps.screenOrientation != oldScreenProps.screenOrientation) {
|
|
744
|
+
[self setScreenOrientation:[RCTConvert UIInterfaceOrientationMask:RCTNSStringFromStringNilIfEmpty(
|
|
745
|
+
newScreenProps.screenOrientation)]];
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
if (newScreenProps.homeIndicatorHidden != oldScreenProps.homeIndicatorHidden) {
|
|
749
|
+
[self setHomeIndicatorHidden:newScreenProps.homeIndicatorHidden];
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
[self setSheetGrabberVisible:newScreenProps.sheetGrabberVisible];
|
|
753
|
+
[self setSheetCornerRadius:newScreenProps.sheetCornerRadius];
|
|
754
|
+
[self setSheetExpandsWhenScrolledToEdge:newScreenProps.sheetExpandsWhenScrolledToEdge];
|
|
755
|
+
|
|
756
|
+
if (newScreenProps.sheetAllowedDetents != oldScreenProps.sheetAllowedDetents) {
|
|
757
|
+
[self setSheetAllowedDetents:[RNSConvert RNSScreenDetentTypeFromAllowedDetents:newScreenProps.sheetAllowedDetents]];
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
if (newScreenProps.sheetLargestUndimmedDetent != oldScreenProps.sheetLargestUndimmedDetent) {
|
|
761
|
+
[self setSheetLargestUndimmedDetent:
|
|
762
|
+
[RNSConvert RNSScreenDetentTypeFromLargestUndimmedDetent:newScreenProps.sheetLargestUndimmedDetent]];
|
|
763
|
+
}
|
|
764
|
+
#endif // !TARGET_OS_TV
|
|
765
|
+
|
|
766
|
+
// Notice that we compare against _stackPresentation, not oldScreenProps.stackPresentation.
|
|
767
|
+
// See comment in prepareForRecycle method for explanation.
|
|
768
|
+
RNSScreenStackPresentation newStackPresentation =
|
|
769
|
+
[RNSConvert RNSScreenStackPresentationFromCppEquivalent:newScreenProps.stackPresentation];
|
|
770
|
+
if (newStackPresentation != _stackPresentation) {
|
|
771
|
+
[self setStackPresentation:newStackPresentation];
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
if (newScreenProps.stackAnimation != oldScreenProps.stackAnimation) {
|
|
775
|
+
[self setStackAnimation:[RNSConvert RNSScreenStackAnimationFromCppEquivalent:newScreenProps.stackAnimation]];
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
if (newScreenProps.replaceAnimation != oldScreenProps.replaceAnimation) {
|
|
779
|
+
[self setReplaceAnimation:[RNSConvert RNSScreenReplaceAnimationFromCppEquivalent:newScreenProps.replaceAnimation]];
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
[super updateProps:props oldProps:oldProps];
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
- (void)updateState:(react::State::Shared const &)state oldState:(react::State::Shared const &)oldState
|
|
786
|
+
{
|
|
787
|
+
_state = std::static_pointer_cast<const react::RNSScreenShadowNode::ConcreteState>(state);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
- (void)updateLayoutMetrics:(const react::LayoutMetrics &)layoutMetrics
|
|
791
|
+
oldLayoutMetrics:(const react::LayoutMetrics &)oldLayoutMetrics
|
|
792
|
+
{
|
|
793
|
+
_newLayoutMetrics = layoutMetrics;
|
|
794
|
+
_oldLayoutMetrics = oldLayoutMetrics;
|
|
795
|
+
UIViewController *parentVC = self.reactViewController.parentViewController;
|
|
796
|
+
if (parentVC != nil && ![parentVC isKindOfClass:[RNSNavigationController class]]) {
|
|
797
|
+
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
798
|
+
}
|
|
799
|
+
// when screen is mounted under RNSNavigationController it's size is controller
|
|
800
|
+
// by the navigation controller itself. That is, it is set to fill space of
|
|
801
|
+
// the controller. In that case we ignore react layout system from managing
|
|
802
|
+
// the screen dimensions and we wait for the screen VC to update and then we
|
|
803
|
+
// pass the dimensions to ui view manager to take into account when laying out
|
|
804
|
+
// subviews
|
|
805
|
+
// Explanation taken from `reactSetFrame`, which is old arch equivalent of this code.
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask
|
|
809
|
+
{
|
|
810
|
+
[super finalizeUpdates:updateMask];
|
|
811
|
+
#if !TARGET_OS_TV
|
|
812
|
+
[self updatePresentationStyle];
|
|
813
|
+
#endif // !TARGET_OS_TV
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
#pragma mark - Paper specific
|
|
817
|
+
#else
|
|
818
|
+
|
|
819
|
+
- (void)didSetProps:(NSArray<NSString *> *)changedProps
|
|
820
|
+
{
|
|
821
|
+
[super didSetProps:changedProps];
|
|
822
|
+
#if !TARGET_OS_TV
|
|
823
|
+
[self updatePresentationStyle];
|
|
824
|
+
#endif // !TARGET_OS_TV
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
- (void)setPointerEvents:(RCTPointerEvents)pointerEvents
|
|
828
|
+
{
|
|
829
|
+
// pointer events settings are managed by the parent screen container, we ignore
|
|
830
|
+
// any attempt of setting that via React props
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
- (void)reactSetFrame:(CGRect)frame
|
|
834
|
+
{
|
|
835
|
+
_reactFrame = frame;
|
|
836
|
+
UIViewController *parentVC = self.reactViewController.parentViewController;
|
|
837
|
+
if (parentVC != nil && ![parentVC isKindOfClass:[RNSNavigationController class]]) {
|
|
838
|
+
[super reactSetFrame:frame];
|
|
839
|
+
}
|
|
840
|
+
// when screen is mounted under RNSNavigationController it's size is controller
|
|
841
|
+
// by the navigation controller itself. That is, it is set to fill space of
|
|
842
|
+
// the controller. In that case we ignore react layout system from managing
|
|
843
|
+
// the screen dimensions and we wait for the screen VC to update and then we
|
|
844
|
+
// pass the dimensions to ui view manager to take into account when laying out
|
|
845
|
+
// subviews
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
- (void)invalidate
|
|
849
|
+
{
|
|
850
|
+
_controller = nil;
|
|
851
|
+
}
|
|
852
|
+
#endif
|
|
853
|
+
|
|
854
|
+
@end
|
|
855
|
+
|
|
856
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
857
|
+
Class<RCTComponentViewProtocol> RNSScreenCls(void)
|
|
858
|
+
{
|
|
859
|
+
return RNSScreenView.class;
|
|
860
|
+
}
|
|
861
|
+
#endif
|
|
862
|
+
|
|
863
|
+
#pragma mark - RNSScreen
|
|
864
|
+
|
|
865
|
+
@implementation RNSScreen {
|
|
866
|
+
__weak id _previousFirstResponder;
|
|
867
|
+
CGRect _lastViewFrame;
|
|
868
|
+
RNSScreenView *_initialView;
|
|
869
|
+
UIView *_fakeView;
|
|
870
|
+
CADisplayLink *_animationTimer;
|
|
871
|
+
CGFloat _currentAlpha;
|
|
872
|
+
BOOL _closing;
|
|
873
|
+
BOOL _goingForward;
|
|
874
|
+
int _dismissCount;
|
|
875
|
+
BOOL _isSwiping;
|
|
876
|
+
BOOL _shouldNotify;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
#pragma mark - Common
|
|
880
|
+
|
|
881
|
+
- (instancetype)initWithView:(UIView *)view
|
|
882
|
+
{
|
|
883
|
+
if (self = [super init]) {
|
|
884
|
+
self.view = view;
|
|
885
|
+
_fakeView = [UIView new];
|
|
886
|
+
_shouldNotify = YES;
|
|
887
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
888
|
+
_initialView = (RNSScreenView *)view;
|
|
889
|
+
#endif
|
|
890
|
+
}
|
|
891
|
+
return self;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
// TODO: Find out why this is executed when screen is going out
|
|
895
|
+
- (void)viewWillAppear:(BOOL)animated
|
|
896
|
+
{
|
|
897
|
+
[super viewWillAppear:animated];
|
|
898
|
+
if (!_isSwiping) {
|
|
899
|
+
[self.screenView notifyWillAppear];
|
|
900
|
+
if (self.transitionCoordinator.isInteractive) {
|
|
901
|
+
// we started dismissing with swipe gesture
|
|
902
|
+
_isSwiping = YES;
|
|
903
|
+
}
|
|
904
|
+
} else {
|
|
905
|
+
// this event is also triggered if we cancelled the swipe.
|
|
906
|
+
// The _isSwiping is still true, but we don't want to notify then
|
|
907
|
+
_shouldNotify = NO;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
[self hideHeaderIfNecessary];
|
|
911
|
+
// as per documentation of these methods
|
|
912
|
+
_goingForward = [self isBeingPresented] || [self isMovingToParentViewController];
|
|
913
|
+
|
|
914
|
+
[RNSScreenWindowTraits updateWindowTraits];
|
|
915
|
+
if (_shouldNotify) {
|
|
916
|
+
_closing = NO;
|
|
917
|
+
[self notifyTransitionProgress:0.0 closing:_closing goingForward:_goingForward];
|
|
918
|
+
[self setupProgressNotification];
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
- (void)viewWillDisappear:(BOOL)animated
|
|
923
|
+
{
|
|
924
|
+
[super viewWillDisappear:animated];
|
|
925
|
+
// self.navigationController might be null when we are dismissing a modal
|
|
926
|
+
if (!self.transitionCoordinator.isInteractive && self.navigationController != nil) {
|
|
927
|
+
// user might have long pressed ios 14 back button item,
|
|
928
|
+
// so he can go back more than one screen and we need to dismiss more screens in JS stack then.
|
|
929
|
+
// We check it by calculating the difference between the index of currently displayed screen
|
|
930
|
+
// and the index of the target screen, which is the view of topViewController at this point.
|
|
931
|
+
// If the value is lower than 1, it means we are dismissing a modal, or navigating forward, or going back with JS.
|
|
932
|
+
int selfIndex = [self getIndexOfView:self.screenView];
|
|
933
|
+
int targetIndex = [self getIndexOfView:self.navigationController.topViewController.view];
|
|
934
|
+
_dismissCount = selfIndex - targetIndex > 0 ? selfIndex - targetIndex : 1;
|
|
935
|
+
} else {
|
|
936
|
+
_dismissCount = 1;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
// same flow as in viewWillAppear
|
|
940
|
+
if (!_isSwiping) {
|
|
941
|
+
[self.screenView notifyWillDisappear];
|
|
942
|
+
if (self.transitionCoordinator.isInteractive) {
|
|
943
|
+
_isSwiping = YES;
|
|
944
|
+
}
|
|
945
|
+
} else {
|
|
946
|
+
_shouldNotify = NO;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// as per documentation of these methods
|
|
950
|
+
_goingForward = !([self isBeingDismissed] || [self isMovingFromParentViewController]);
|
|
951
|
+
|
|
952
|
+
if (_shouldNotify) {
|
|
953
|
+
_closing = YES;
|
|
954
|
+
[self notifyTransitionProgress:0.0 closing:_closing goingForward:_goingForward];
|
|
955
|
+
[self setupProgressNotification];
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
- (void)viewDidAppear:(BOOL)animated
|
|
960
|
+
{
|
|
961
|
+
[super viewDidAppear:animated];
|
|
962
|
+
if (!_isSwiping || _shouldNotify) {
|
|
963
|
+
// we are going forward or dismissing without swipe
|
|
964
|
+
// or successfully swiped back
|
|
965
|
+
[self.screenView notifyAppear];
|
|
966
|
+
[self notifyTransitionProgress:1.0 closing:NO goingForward:_goingForward];
|
|
967
|
+
} else {
|
|
968
|
+
[self.screenView notifyGestureCancel];
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
_isSwiping = NO;
|
|
972
|
+
_shouldNotify = YES;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
- (void)viewDidDisappear:(BOOL)animated
|
|
976
|
+
{
|
|
977
|
+
[super viewDidDisappear:animated];
|
|
978
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
979
|
+
[self resetViewToScreen];
|
|
980
|
+
#endif
|
|
981
|
+
if (self.parentViewController == nil && self.presentingViewController == nil) {
|
|
982
|
+
if (self.screenView.preventNativeDismiss) {
|
|
983
|
+
// if we want to prevent the native dismiss, we do not send dismissal event,
|
|
984
|
+
// but instead call `updateContainer`, which restores the JS navigation stack
|
|
985
|
+
[self.screenView.reactSuperview updateContainer];
|
|
986
|
+
[self.screenView notifyDismissCancelledWithDismissCount:_dismissCount];
|
|
987
|
+
} else {
|
|
988
|
+
// screen dismissed, send event
|
|
989
|
+
[self.screenView notifyDismissedWithCount:_dismissCount];
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
// same flow as in viewDidAppear
|
|
993
|
+
if (!_isSwiping || _shouldNotify) {
|
|
994
|
+
[self.screenView notifyDisappear];
|
|
995
|
+
[self notifyTransitionProgress:1.0 closing:YES goingForward:_goingForward];
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
_isSwiping = NO;
|
|
999
|
+
_shouldNotify = YES;
|
|
1000
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
1001
|
+
#else
|
|
1002
|
+
[self traverseForScrollView:self.screenView];
|
|
1003
|
+
#endif
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
- (void)viewDidLayoutSubviews
|
|
1007
|
+
{
|
|
1008
|
+
[super viewDidLayoutSubviews];
|
|
1009
|
+
|
|
1010
|
+
// The below code makes the screen view adapt dimensions provided by the system. We take these
|
|
1011
|
+
// into account only when the view is mounted under RNSNavigationController in which case system
|
|
1012
|
+
// provides additional padding to account for possible header, and in the case when screen is
|
|
1013
|
+
// shown as a native modal, as the final dimensions of the modal on iOS 12+ are shorter than the
|
|
1014
|
+
// screen size
|
|
1015
|
+
BOOL isDisplayedWithinUINavController = [self.parentViewController isKindOfClass:[RNSNavigationController class]];
|
|
1016
|
+
|
|
1017
|
+
// Calculate header height on modal open
|
|
1018
|
+
if (self.screenView.isPresentedAsNativeModal) {
|
|
1019
|
+
[self calculateAndNotifyHeaderHeightChangeIsModal:YES];
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
if (isDisplayedWithinUINavController || self.screenView.isPresentedAsNativeModal) {
|
|
1023
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
1024
|
+
[self.screenView updateBounds];
|
|
1025
|
+
#else
|
|
1026
|
+
if (!CGRectEqualToRect(_lastViewFrame, self.screenView.frame)) {
|
|
1027
|
+
_lastViewFrame = self.screenView.frame;
|
|
1028
|
+
[((RNSScreenView *)self.viewIfLoaded) updateBounds];
|
|
1029
|
+
}
|
|
1030
|
+
#endif
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
// Checks whether this screen has any child view controllers of type RNSNavigationController.
|
|
1035
|
+
// Useful for checking if this screen has nested stack or is displayed at the top.
|
|
1036
|
+
- (BOOL)hasNestedStack
|
|
1037
|
+
{
|
|
1038
|
+
for (UIViewController *vc in self.childViewControllers) {
|
|
1039
|
+
if ([vc isKindOfClass:[RNSNavigationController class]]) {
|
|
1040
|
+
return YES;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
return NO;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
- (CGFloat)getCalculatedHeaderHeightIsModal:(BOOL)isModal
|
|
1048
|
+
{
|
|
1049
|
+
CGFloat navbarHeight = self.navigationController.navigationBar.frame.size.height;
|
|
1050
|
+
|
|
1051
|
+
// In case where screen is a modal, we want to calculate just its childViewController's height
|
|
1052
|
+
if (isModal && self.childViewControllers.count > 0 &&
|
|
1053
|
+
[self.childViewControllers[0] isKindOfClass:UINavigationController.class]) {
|
|
1054
|
+
UINavigationController *childNavCtr = self.childViewControllers[0];
|
|
1055
|
+
navbarHeight = childNavCtr.navigationBar.frame.size.height;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
return navbarHeight;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
- (CGSize)getCalculatedStatusBarHeightIsModal:(BOOL)isModal
|
|
1062
|
+
{
|
|
1063
|
+
#if !TARGET_OS_TV
|
|
1064
|
+
BOOL isDraggableModal = isModal && ![self.screenView isFullscreenModal];
|
|
1065
|
+
BOOL isDraggableModalWithChildViewCtr =
|
|
1066
|
+
isDraggableModal && self.childViewControllers.count > 0 && self.childViewControllers[0] != nil;
|
|
1067
|
+
|
|
1068
|
+
// When modal is floating (we can grab its header), we don't want to calculate status bar in it.
|
|
1069
|
+
// Thus, we return '0' as a height of status bar.
|
|
1070
|
+
if (isDraggableModalWithChildViewCtr || self.screenView.isTransparentModal) {
|
|
1071
|
+
return CGSizeMake(0, 0);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
CGSize fallbackStatusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;
|
|
1075
|
+
|
|
1076
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
|
|
1077
|
+
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
|
|
1078
|
+
if (@available(iOS 13.0, *)) {
|
|
1079
|
+
CGSize primaryStatusBarSize = self.view.window.windowScene.statusBarManager.statusBarFrame.size;
|
|
1080
|
+
if (primaryStatusBarSize.height == 0 || primaryStatusBarSize.width == 0)
|
|
1081
|
+
return fallbackStatusBarSize;
|
|
1082
|
+
|
|
1083
|
+
return primaryStatusBarSize;
|
|
1084
|
+
} else {
|
|
1085
|
+
return fallbackStatusBarSize;
|
|
1086
|
+
}
|
|
1087
|
+
#endif /* Check for iOS 13.0 */
|
|
1088
|
+
|
|
1089
|
+
#else
|
|
1090
|
+
// On TVOS, status bar doesn't exist
|
|
1091
|
+
return CGSizeMake(0, 0);
|
|
1092
|
+
#endif // !TARGET_OS_TV
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
- (CGFloat)calculateHeaderHeightIsModal:(BOOL)isModal
|
|
1096
|
+
{
|
|
1097
|
+
CGFloat navbarHeight = [self getCalculatedHeaderHeightIsModal:isModal];
|
|
1098
|
+
CGSize statusBarSize = [self getCalculatedStatusBarHeightIsModal:isModal];
|
|
1099
|
+
|
|
1100
|
+
// Unfortunately, UIKit doesn't care about switching width and height options on screen rotation.
|
|
1101
|
+
// We should check if user has rotated its screen, so we're choosing the minimum value between the
|
|
1102
|
+
// width and height.
|
|
1103
|
+
CGFloat statusBarHeight = MIN(statusBarSize.width, statusBarSize.height);
|
|
1104
|
+
return navbarHeight + statusBarHeight;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
- (void)calculateAndNotifyHeaderHeightChangeIsModal:(BOOL)isModal
|
|
1108
|
+
{
|
|
1109
|
+
CGFloat totalHeight = [self calculateHeaderHeightIsModal:isModal];
|
|
1110
|
+
[self.screenView notifyHeaderHeightChange:totalHeight];
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
- (void)notifyFinishTransitioning
|
|
1114
|
+
{
|
|
1115
|
+
[_previousFirstResponder becomeFirstResponder];
|
|
1116
|
+
_previousFirstResponder = nil;
|
|
1117
|
+
// the correct Screen for appearance is set after the transition, same for orientation.
|
|
1118
|
+
[RNSScreenWindowTraits updateWindowTraits];
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
- (void)willMoveToParentViewController:(UIViewController *)parent
|
|
1122
|
+
{
|
|
1123
|
+
[super willMoveToParentViewController:parent];
|
|
1124
|
+
if (parent == nil) {
|
|
1125
|
+
id responder = [self findFirstResponder:self.screenView];
|
|
1126
|
+
if (responder != nil) {
|
|
1127
|
+
_previousFirstResponder = responder;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
- (id)findFirstResponder:(UIView *)parent
|
|
1133
|
+
{
|
|
1134
|
+
if (parent.isFirstResponder) {
|
|
1135
|
+
return parent;
|
|
1136
|
+
}
|
|
1137
|
+
for (UIView *subView in parent.subviews) {
|
|
1138
|
+
id responder = [self findFirstResponder:subView];
|
|
1139
|
+
if (responder != nil) {
|
|
1140
|
+
return responder;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
return nil;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
#pragma mark - transition progress related methods
|
|
1147
|
+
|
|
1148
|
+
- (void)setupProgressNotification
|
|
1149
|
+
{
|
|
1150
|
+
if (self.transitionCoordinator != nil) {
|
|
1151
|
+
_fakeView.alpha = 0.0;
|
|
1152
|
+
[self.transitionCoordinator
|
|
1153
|
+
animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
|
1154
|
+
[[context containerView] addSubview:self->_fakeView];
|
|
1155
|
+
self->_fakeView.alpha = 1.0;
|
|
1156
|
+
self->_animationTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleAnimation)];
|
|
1157
|
+
[self->_animationTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
|
1158
|
+
}
|
|
1159
|
+
completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
|
1160
|
+
[self->_animationTimer setPaused:YES];
|
|
1161
|
+
[self->_animationTimer invalidate];
|
|
1162
|
+
[self->_fakeView removeFromSuperview];
|
|
1163
|
+
}];
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
- (void)handleAnimation
|
|
1168
|
+
{
|
|
1169
|
+
if ([[_fakeView layer] presentationLayer] != nil) {
|
|
1170
|
+
CGFloat fakeViewAlpha = _fakeView.layer.presentationLayer.opacity;
|
|
1171
|
+
if (_currentAlpha != fakeViewAlpha) {
|
|
1172
|
+
_currentAlpha = fmax(0.0, fmin(1.0, fakeViewAlpha));
|
|
1173
|
+
[self notifyTransitionProgress:_currentAlpha closing:_closing goingForward:_goingForward];
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
- (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward
|
|
1179
|
+
{
|
|
1180
|
+
if ([self.view isKindOfClass:[RNSScreenView class]]) {
|
|
1181
|
+
// if the view is already snapshot, there is not sense in sending progress since on JS side
|
|
1182
|
+
// the component is already not present
|
|
1183
|
+
[(RNSScreenView *)self.view notifyTransitionProgress:progress closing:closing goingForward:goingForward];
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
#if !TARGET_OS_TV
|
|
1188
|
+
// if the returned vc is a child, it means that it can provide config;
|
|
1189
|
+
// if the returned vc is self, it means that there is no child for config and self has config to provide,
|
|
1190
|
+
// so we return self which results in asking self for preferredStatusBarStyle/Animation etc.;
|
|
1191
|
+
// if the returned vc is nil, it means none of children could provide config and self does not have config either,
|
|
1192
|
+
// so if it was asked by parent, it will fallback to parent's option, or use default option if it is the top Screen
|
|
1193
|
+
- (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includingModals:(BOOL)includingModals
|
|
1194
|
+
{
|
|
1195
|
+
UIViewController *lastViewController = [[self childViewControllers] lastObject];
|
|
1196
|
+
if ([self.presentedViewController isKindOfClass:[RNSScreen class]]) {
|
|
1197
|
+
lastViewController = self.presentedViewController;
|
|
1198
|
+
// we don't want to allow controlling of status bar appearance when we present non-fullScreen modal
|
|
1199
|
+
// and it is not possible if `modalPresentationCapturesStatusBarAppearance` is not set to YES, so even
|
|
1200
|
+
// if we went into a modal here and ask it, it wouldn't take any effect. For fullScreen modals, the system
|
|
1201
|
+
// asks them by itself, so we can stop traversing here.
|
|
1202
|
+
// for screen orientation, we need to start the search again from that modal
|
|
1203
|
+
return !includingModals
|
|
1204
|
+
? nil
|
|
1205
|
+
: [(RNSScreen *)lastViewController findChildVCForConfigAndTrait:trait includingModals:includingModals]
|
|
1206
|
+
?: lastViewController;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
UIViewController *selfOrNil = [self hasTraitSet:trait] ? self : nil;
|
|
1210
|
+
if (lastViewController == nil) {
|
|
1211
|
+
return selfOrNil;
|
|
1212
|
+
} else {
|
|
1213
|
+
if ([lastViewController conformsToProtocol:@protocol(RNSViewControllerDelegate)]) {
|
|
1214
|
+
// If there is a child (should be VC of ScreenContainer or ScreenStack), that has a child that could provide the
|
|
1215
|
+
// trait, we recursively go into its findChildVCForConfig, and if one of the children has the trait set, we return
|
|
1216
|
+
// it, otherwise we return self if this VC has config, and nil if it doesn't we use
|
|
1217
|
+
// `childViewControllerForStatusBarStyle` for all options since the behavior is the same for all of them
|
|
1218
|
+
UIViewController *childScreen = [lastViewController childViewControllerForStatusBarStyle];
|
|
1219
|
+
if ([childScreen isKindOfClass:[RNSScreen class]]) {
|
|
1220
|
+
return [(RNSScreen *)childScreen findChildVCForConfigAndTrait:trait includingModals:includingModals]
|
|
1221
|
+
?: selfOrNil;
|
|
1222
|
+
} else {
|
|
1223
|
+
return selfOrNil;
|
|
1224
|
+
}
|
|
1225
|
+
} else {
|
|
1226
|
+
// child vc is not from this library, so we don't ask it
|
|
1227
|
+
return selfOrNil;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
- (BOOL)hasTraitSet:(RNSWindowTrait)trait
|
|
1233
|
+
{
|
|
1234
|
+
switch (trait) {
|
|
1235
|
+
case RNSWindowTraitStyle: {
|
|
1236
|
+
return self.screenView.hasStatusBarStyleSet;
|
|
1237
|
+
}
|
|
1238
|
+
case RNSWindowTraitAnimation: {
|
|
1239
|
+
return self.screenView.hasStatusBarAnimationSet;
|
|
1240
|
+
}
|
|
1241
|
+
case RNSWindowTraitHidden: {
|
|
1242
|
+
return self.screenView.hasStatusBarHiddenSet;
|
|
1243
|
+
}
|
|
1244
|
+
case RNSWindowTraitOrientation: {
|
|
1245
|
+
return self.screenView.hasOrientationSet;
|
|
1246
|
+
}
|
|
1247
|
+
case RNSWindowTraitHomeIndicatorHidden: {
|
|
1248
|
+
return self.screenView.hasHomeIndicatorHiddenSet;
|
|
1249
|
+
}
|
|
1250
|
+
default: {
|
|
1251
|
+
RCTLogError(@"Unknown trait passed: %d", (int)trait);
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
return NO;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
- (UIViewController *)childViewControllerForStatusBarHidden
|
|
1258
|
+
{
|
|
1259
|
+
UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitHidden includingModals:NO];
|
|
1260
|
+
return vc == self ? nil : vc;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
- (BOOL)prefersStatusBarHidden
|
|
1264
|
+
{
|
|
1265
|
+
return self.screenView.statusBarHidden;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
- (UIViewController *)childViewControllerForStatusBarStyle
|
|
1269
|
+
{
|
|
1270
|
+
UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitStyle includingModals:NO];
|
|
1271
|
+
return vc == self ? nil : vc;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
- (UIStatusBarStyle)preferredStatusBarStyle
|
|
1275
|
+
{
|
|
1276
|
+
return [RNSScreenWindowTraits statusBarStyleForRNSStatusBarStyle:self.screenView.statusBarStyle];
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
|
|
1280
|
+
{
|
|
1281
|
+
UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitAnimation includingModals:NO];
|
|
1282
|
+
|
|
1283
|
+
if ([vc isKindOfClass:[RNSScreen class]]) {
|
|
1284
|
+
return ((RNSScreen *)vc).screenView.statusBarAnimation;
|
|
1285
|
+
}
|
|
1286
|
+
return UIStatusBarAnimationFade;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
|
|
1290
|
+
{
|
|
1291
|
+
UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitOrientation includingModals:YES];
|
|
1292
|
+
|
|
1293
|
+
if ([vc isKindOfClass:[RNSScreen class]]) {
|
|
1294
|
+
return ((RNSScreen *)vc).screenView.screenOrientation;
|
|
1295
|
+
}
|
|
1296
|
+
return UIInterfaceOrientationMaskAllButUpsideDown;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
- (UIViewController *)childViewControllerForHomeIndicatorAutoHidden
|
|
1300
|
+
{
|
|
1301
|
+
UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitHomeIndicatorHidden includingModals:YES];
|
|
1302
|
+
return vc == self ? nil : vc;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
- (BOOL)prefersHomeIndicatorAutoHidden
|
|
1306
|
+
{
|
|
1307
|
+
return self.screenView.homeIndicatorHidden;
|
|
1308
|
+
}
|
|
1309
|
+
- (int)getParentChildrenCount
|
|
1310
|
+
{
|
|
1311
|
+
return (int)[[self.screenView.reactSuperview reactSubviews] count];
|
|
1312
|
+
}
|
|
1313
|
+
#endif
|
|
1314
|
+
|
|
1315
|
+
- (int)getIndexOfView:(UIView *)view
|
|
1316
|
+
{
|
|
1317
|
+
return (int)[[self.screenView.reactSuperview reactSubviews] indexOfObject:view];
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
// since on Fabric the view of controller can be a snapshot of type `UIView`,
|
|
1321
|
+
// when we want to check props of ScreenView, we need to get them from _initialView
|
|
1322
|
+
- (RNSScreenView *)screenView
|
|
1323
|
+
{
|
|
1324
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
1325
|
+
return _initialView;
|
|
1326
|
+
#else
|
|
1327
|
+
return (RNSScreenView *)self.view;
|
|
1328
|
+
#endif
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
- (void)hideHeaderIfNecessary
|
|
1332
|
+
{
|
|
1333
|
+
#if !TARGET_OS_TV
|
|
1334
|
+
// On iOS >=13, there is a bug when user transitions from screen with active search bar to screen without header
|
|
1335
|
+
// In that case default iOS header will be shown. To fix this we hide header when the screens that appears has header
|
|
1336
|
+
// hidden and search bar was active on previous screen. We need to do it asynchronously, because default header is
|
|
1337
|
+
// added after viewWillAppear.
|
|
1338
|
+
if (@available(iOS 13.0, *)) {
|
|
1339
|
+
NSUInteger currentIndex = [self.navigationController.viewControllers indexOfObject:self];
|
|
1340
|
+
|
|
1341
|
+
// we need to check whether reactSubviews array is empty, because on Fabric child nodes are unmounted first ->
|
|
1342
|
+
// reactSubviews array may be empty
|
|
1343
|
+
RNSScreenStackHeaderConfig *config = [self.screenView findHeaderConfig];
|
|
1344
|
+
if (currentIndex > 0 && config != nil) {
|
|
1345
|
+
UINavigationItem *prevNavigationItem =
|
|
1346
|
+
[self.navigationController.viewControllers objectAtIndex:currentIndex - 1].navigationItem;
|
|
1347
|
+
BOOL wasSearchBarActive = prevNavigationItem.searchController.active;
|
|
1348
|
+
|
|
1349
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
1350
|
+
BOOL shouldHideHeader = !config.show;
|
|
1351
|
+
#else
|
|
1352
|
+
BOOL shouldHideHeader = config.hide;
|
|
1353
|
+
#endif
|
|
1354
|
+
|
|
1355
|
+
if (wasSearchBarActive && shouldHideHeader) {
|
|
1356
|
+
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0);
|
|
1357
|
+
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
|
|
1358
|
+
[self.navigationController setNavigationBarHidden:YES animated:NO];
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
#endif
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
1367
|
+
#pragma mark - Fabric specific
|
|
1368
|
+
|
|
1369
|
+
- (void)setViewToSnapshot:(UIView *)snapshot
|
|
1370
|
+
{
|
|
1371
|
+
// modals of native stack seem not to support
|
|
1372
|
+
// changing their view by just setting the view
|
|
1373
|
+
if (_initialView.stackPresentation != RNSScreenStackPresentationPush) {
|
|
1374
|
+
UIView *superView = self.view.superview;
|
|
1375
|
+
[self.view removeFromSuperview];
|
|
1376
|
+
self.view = snapshot;
|
|
1377
|
+
[superView addSubview:self.view];
|
|
1378
|
+
} else {
|
|
1379
|
+
[self.view removeFromSuperview];
|
|
1380
|
+
self.view = snapshot;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
- (void)resetViewToScreen
|
|
1385
|
+
{
|
|
1386
|
+
if (self.view != _initialView) {
|
|
1387
|
+
[self.view removeFromSuperview];
|
|
1388
|
+
self.view = _initialView;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
#else
|
|
1393
|
+
#pragma mark - Paper specific
|
|
1394
|
+
|
|
1395
|
+
- (void)traverseForScrollView:(UIView *)view
|
|
1396
|
+
{
|
|
1397
|
+
if (![[self.view valueForKey:@"_bridge"] valueForKey:@"_jsThread"]) {
|
|
1398
|
+
// we don't want to send `scrollViewDidEndDecelerating` event to JS before the JS thread is ready
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
if ([view isKindOfClass:[UIScrollView class]] &&
|
|
1402
|
+
([[(UIScrollView *)view delegate] respondsToSelector:@selector(scrollViewDidEndDecelerating:)])) {
|
|
1403
|
+
[[(UIScrollView *)view delegate] scrollViewDidEndDecelerating:(id)view];
|
|
1404
|
+
}
|
|
1405
|
+
[view.subviews enumerateObjectsUsingBlock:^(__kindof UIView *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
|
|
1406
|
+
[self traverseForScrollView:obj];
|
|
1407
|
+
}];
|
|
1408
|
+
}
|
|
1409
|
+
#endif
|
|
1410
|
+
|
|
1411
|
+
@end
|
|
1412
|
+
|
|
1413
|
+
@implementation RNSScreenManager
|
|
1414
|
+
|
|
1415
|
+
RCT_EXPORT_MODULE()
|
|
1416
|
+
|
|
1417
|
+
// we want to handle the case when activityState is nil
|
|
1418
|
+
RCT_REMAP_VIEW_PROPERTY(activityState, activityStateOrNil, NSNumber)
|
|
1419
|
+
RCT_EXPORT_VIEW_PROPERTY(customAnimationOnSwipe, BOOL);
|
|
1420
|
+
RCT_EXPORT_VIEW_PROPERTY(fullScreenSwipeEnabled, BOOL);
|
|
1421
|
+
RCT_EXPORT_VIEW_PROPERTY(gestureEnabled, BOOL)
|
|
1422
|
+
RCT_EXPORT_VIEW_PROPERTY(gestureResponseDistance, NSDictionary)
|
|
1423
|
+
RCT_EXPORT_VIEW_PROPERTY(hideKeyboardOnSwipe, BOOL)
|
|
1424
|
+
RCT_EXPORT_VIEW_PROPERTY(preventNativeDismiss, BOOL)
|
|
1425
|
+
RCT_EXPORT_VIEW_PROPERTY(replaceAnimation, RNSScreenReplaceAnimation)
|
|
1426
|
+
RCT_EXPORT_VIEW_PROPERTY(stackPresentation, RNSScreenStackPresentation)
|
|
1427
|
+
RCT_EXPORT_VIEW_PROPERTY(stackAnimation, RNSScreenStackAnimation)
|
|
1428
|
+
RCT_EXPORT_VIEW_PROPERTY(swipeDirection, RNSScreenSwipeDirection)
|
|
1429
|
+
RCT_EXPORT_VIEW_PROPERTY(transitionDuration, NSNumber)
|
|
1430
|
+
|
|
1431
|
+
RCT_EXPORT_VIEW_PROPERTY(onAppear, RCTDirectEventBlock);
|
|
1432
|
+
RCT_EXPORT_VIEW_PROPERTY(onDisappear, RCTDirectEventBlock);
|
|
1433
|
+
RCT_EXPORT_VIEW_PROPERTY(onHeaderHeightChange, RCTDirectEventBlock);
|
|
1434
|
+
RCT_EXPORT_VIEW_PROPERTY(onDismissed, RCTDirectEventBlock);
|
|
1435
|
+
RCT_EXPORT_VIEW_PROPERTY(onNativeDismissCancelled, RCTDirectEventBlock);
|
|
1436
|
+
RCT_EXPORT_VIEW_PROPERTY(onTransitionProgress, RCTDirectEventBlock);
|
|
1437
|
+
RCT_EXPORT_VIEW_PROPERTY(onWillAppear, RCTDirectEventBlock);
|
|
1438
|
+
RCT_EXPORT_VIEW_PROPERTY(onWillDisappear, RCTDirectEventBlock);
|
|
1439
|
+
RCT_EXPORT_VIEW_PROPERTY(onGestureCancel, RCTDirectEventBlock);
|
|
1440
|
+
|
|
1441
|
+
#if !TARGET_OS_TV
|
|
1442
|
+
RCT_EXPORT_VIEW_PROPERTY(screenOrientation, UIInterfaceOrientationMask)
|
|
1443
|
+
RCT_EXPORT_VIEW_PROPERTY(statusBarAnimation, UIStatusBarAnimation)
|
|
1444
|
+
RCT_EXPORT_VIEW_PROPERTY(statusBarHidden, BOOL)
|
|
1445
|
+
RCT_EXPORT_VIEW_PROPERTY(statusBarStyle, RNSStatusBarStyle)
|
|
1446
|
+
RCT_EXPORT_VIEW_PROPERTY(homeIndicatorHidden, BOOL)
|
|
1447
|
+
|
|
1448
|
+
RCT_EXPORT_VIEW_PROPERTY(sheetAllowedDetents, RNSScreenDetentType);
|
|
1449
|
+
RCT_EXPORT_VIEW_PROPERTY(sheetLargestUndimmedDetent, RNSScreenDetentType);
|
|
1450
|
+
RCT_EXPORT_VIEW_PROPERTY(sheetGrabberVisible, BOOL);
|
|
1451
|
+
RCT_EXPORT_VIEW_PROPERTY(sheetCornerRadius, CGFloat);
|
|
1452
|
+
RCT_EXPORT_VIEW_PROPERTY(sheetExpandsWhenScrolledToEdge, BOOL);
|
|
1453
|
+
#endif
|
|
1454
|
+
|
|
1455
|
+
#if !TARGET_OS_TV
|
|
1456
|
+
// See:
|
|
1457
|
+
// 1. https://github.com/software-mansion/react-native-screens/pull/1543
|
|
1458
|
+
// 2. https://github.com/software-mansion/react-native-screens/pull/1596
|
|
1459
|
+
// This class is instatiated from React Native's internals during application startup
|
|
1460
|
+
- (instancetype)init
|
|
1461
|
+
{
|
|
1462
|
+
if (self = [super init]) {
|
|
1463
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
1464
|
+
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
|
|
1465
|
+
});
|
|
1466
|
+
}
|
|
1467
|
+
return self;
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
- (void)dealloc
|
|
1471
|
+
{
|
|
1472
|
+
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
1473
|
+
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
|
|
1474
|
+
});
|
|
1475
|
+
}
|
|
1476
|
+
#endif // !TARGET_OS_TV
|
|
1477
|
+
|
|
1478
|
+
- (UIView *)view
|
|
1479
|
+
{
|
|
1480
|
+
return [[RNSScreenView alloc] initWithBridge:self.bridge];
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
+ (BOOL)requiresMainQueueSetup
|
|
1484
|
+
{
|
|
1485
|
+
// Returning NO here despite the fact some initialization in -init method dispatches tasks
|
|
1486
|
+
// on main queue, because the comments in RN source code states that modules which return YES
|
|
1487
|
+
// here will be constructed ahead-of-time -- and this is not required in our case.
|
|
1488
|
+
return NO;
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
@end
|
|
1492
|
+
|
|
1493
|
+
@implementation RCTConvert (RNSScreen)
|
|
1494
|
+
|
|
1495
|
+
RCT_ENUM_CONVERTER(
|
|
1496
|
+
RNSScreenStackPresentation,
|
|
1497
|
+
(@{
|
|
1498
|
+
@"push" : @(RNSScreenStackPresentationPush),
|
|
1499
|
+
@"modal" : @(RNSScreenStackPresentationModal),
|
|
1500
|
+
@"fullScreenModal" : @(RNSScreenStackPresentationFullScreenModal),
|
|
1501
|
+
@"formSheet" : @(RNSScreenStackPresentationFormSheet),
|
|
1502
|
+
@"containedModal" : @(RNSScreenStackPresentationContainedModal),
|
|
1503
|
+
@"transparentModal" : @(RNSScreenStackPresentationTransparentModal),
|
|
1504
|
+
@"containedTransparentModal" : @(RNSScreenStackPresentationContainedTransparentModal)
|
|
1505
|
+
}),
|
|
1506
|
+
RNSScreenStackPresentationPush,
|
|
1507
|
+
integerValue)
|
|
1508
|
+
|
|
1509
|
+
RCT_ENUM_CONVERTER(
|
|
1510
|
+
RNSScreenStackAnimation,
|
|
1511
|
+
(@{
|
|
1512
|
+
@"default" : @(RNSScreenStackAnimationDefault),
|
|
1513
|
+
@"none" : @(RNSScreenStackAnimationNone),
|
|
1514
|
+
@"fade" : @(RNSScreenStackAnimationFade),
|
|
1515
|
+
@"fade_from_bottom" : @(RNSScreenStackAnimationFadeFromBottom),
|
|
1516
|
+
@"flip" : @(RNSScreenStackAnimationFlip),
|
|
1517
|
+
@"simple_push" : @(RNSScreenStackAnimationSimplePush),
|
|
1518
|
+
@"slide_from_bottom" : @(RNSScreenStackAnimationSlideFromBottom),
|
|
1519
|
+
@"slide_from_right" : @(RNSScreenStackAnimationDefault),
|
|
1520
|
+
@"slide_from_left" : @(RNSScreenStackAnimationDefault),
|
|
1521
|
+
}),
|
|
1522
|
+
RNSScreenStackAnimationDefault,
|
|
1523
|
+
integerValue)
|
|
1524
|
+
|
|
1525
|
+
RCT_ENUM_CONVERTER(
|
|
1526
|
+
RNSScreenReplaceAnimation,
|
|
1527
|
+
(@{
|
|
1528
|
+
@"push" : @(RNSScreenReplaceAnimationPush),
|
|
1529
|
+
@"pop" : @(RNSScreenReplaceAnimationPop),
|
|
1530
|
+
}),
|
|
1531
|
+
RNSScreenReplaceAnimationPop,
|
|
1532
|
+
integerValue)
|
|
1533
|
+
|
|
1534
|
+
RCT_ENUM_CONVERTER(
|
|
1535
|
+
RNSScreenSwipeDirection,
|
|
1536
|
+
(@{
|
|
1537
|
+
@"vertical" : @(RNSScreenSwipeDirectionVertical),
|
|
1538
|
+
@"horizontal" : @(RNSScreenSwipeDirectionHorizontal),
|
|
1539
|
+
}),
|
|
1540
|
+
RNSScreenSwipeDirectionHorizontal,
|
|
1541
|
+
integerValue)
|
|
1542
|
+
|
|
1543
|
+
#if !TARGET_OS_TV
|
|
1544
|
+
RCT_ENUM_CONVERTER(
|
|
1545
|
+
UIStatusBarAnimation,
|
|
1546
|
+
(@{
|
|
1547
|
+
@"none" : @(UIStatusBarAnimationNone),
|
|
1548
|
+
@"fade" : @(UIStatusBarAnimationFade),
|
|
1549
|
+
@"slide" : @(UIStatusBarAnimationSlide)
|
|
1550
|
+
}),
|
|
1551
|
+
UIStatusBarAnimationNone,
|
|
1552
|
+
integerValue)
|
|
1553
|
+
|
|
1554
|
+
RCT_ENUM_CONVERTER(
|
|
1555
|
+
RNSStatusBarStyle,
|
|
1556
|
+
(@{
|
|
1557
|
+
@"auto" : @(RNSStatusBarStyleAuto),
|
|
1558
|
+
@"inverted" : @(RNSStatusBarStyleInverted),
|
|
1559
|
+
@"light" : @(RNSStatusBarStyleLight),
|
|
1560
|
+
@"dark" : @(RNSStatusBarStyleDark),
|
|
1561
|
+
}),
|
|
1562
|
+
RNSStatusBarStyleAuto,
|
|
1563
|
+
integerValue)
|
|
1564
|
+
|
|
1565
|
+
RCT_ENUM_CONVERTER(
|
|
1566
|
+
RNSScreenDetentType,
|
|
1567
|
+
(@{
|
|
1568
|
+
@"large" : @(RNSScreenDetentTypeLarge),
|
|
1569
|
+
@"medium" : @(RNSScreenDetentTypeMedium),
|
|
1570
|
+
@"all" : @(RNSScreenDetentTypeAll),
|
|
1571
|
+
}),
|
|
1572
|
+
RNSScreenDetentTypeAll,
|
|
1573
|
+
integerValue)
|
|
1574
|
+
|
|
1575
|
+
+ (UIInterfaceOrientationMask)UIInterfaceOrientationMask:(id)json
|
|
1576
|
+
{
|
|
1577
|
+
json = [self NSString:json];
|
|
1578
|
+
if ([json isEqualToString:@"default"]) {
|
|
1579
|
+
return UIInterfaceOrientationMaskAllButUpsideDown;
|
|
1580
|
+
} else if ([json isEqualToString:@"all"]) {
|
|
1581
|
+
return UIInterfaceOrientationMaskAll;
|
|
1582
|
+
} else if ([json isEqualToString:@"portrait"]) {
|
|
1583
|
+
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
|
|
1584
|
+
} else if ([json isEqualToString:@"portrait_up"]) {
|
|
1585
|
+
return UIInterfaceOrientationMaskPortrait;
|
|
1586
|
+
} else if ([json isEqualToString:@"portrait_down"]) {
|
|
1587
|
+
return UIInterfaceOrientationMaskPortraitUpsideDown;
|
|
1588
|
+
} else if ([json isEqualToString:@"landscape"]) {
|
|
1589
|
+
return UIInterfaceOrientationMaskLandscape;
|
|
1590
|
+
} else if ([json isEqualToString:@"landscape_left"]) {
|
|
1591
|
+
return UIInterfaceOrientationMaskLandscapeLeft;
|
|
1592
|
+
} else if ([json isEqualToString:@"landscape_right"]) {
|
|
1593
|
+
return UIInterfaceOrientationMaskLandscapeRight;
|
|
1594
|
+
}
|
|
1595
|
+
return UIInterfaceOrientationMaskAllButUpsideDown;
|
|
1596
|
+
}
|
|
1597
|
+
#endif
|
|
1598
|
+
|
|
1599
|
+
@end
|