react-native-screens 4.0.0-beta.9 → 4.0.0

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.
Files changed (261) hide show
  1. package/README.md +9 -2
  2. package/android/CMakeLists.txt +28 -19
  3. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +13 -3
  4. package/android/src/main/java/com/swmansion/rnscreens/NativeDismissalObserver.kt +12 -0
  5. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +4 -0
  6. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +64 -68
  7. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetBehaviorExt.kt +42 -0
  8. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingFragment.kt +24 -19
  9. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetUtils.kt +8 -0
  10. package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +10 -3
  11. package/android/src/main/jni/CMakeLists.txt +28 -19
  12. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +2 -2
  13. package/ios/RNSConvert.h +13 -4
  14. package/ios/RNSConvert.mm +50 -28
  15. package/ios/RNSEnums.h +47 -0
  16. package/ios/RNSPercentDrivenInteractiveTransition.h +12 -0
  17. package/ios/RNSPercentDrivenInteractiveTransition.mm +69 -0
  18. package/ios/RNSScreen.h +14 -0
  19. package/ios/RNSScreen.mm +30 -9
  20. package/ios/RNSScreenStack.mm +72 -8
  21. package/ios/RNSScreenStackAnimator.h +13 -1
  22. package/ios/RNSScreenStackAnimator.mm +233 -130
  23. package/ios/RNSScreenStackHeaderConfig.h +1 -1
  24. package/ios/RNSScreenStackHeaderConfig.mm +39 -29
  25. package/lib/commonjs/components/DebugContainer.js +40 -0
  26. package/lib/commonjs/components/DebugContainer.js.map +1 -0
  27. package/lib/commonjs/components/DebugContainer.web.js +15 -0
  28. package/lib/commonjs/components/DebugContainer.web.js.map +1 -0
  29. package/lib/commonjs/components/FullWindowOverlay.js +8 -5
  30. package/lib/commonjs/components/FullWindowOverlay.js.map +1 -1
  31. package/lib/commonjs/components/Screen.js +28 -10
  32. package/lib/commonjs/components/Screen.js.map +1 -1
  33. package/lib/commonjs/components/ScreenContainer.js +3 -5
  34. package/lib/commonjs/components/ScreenContainer.js.map +1 -1
  35. package/lib/commonjs/components/ScreenContainer.web.js +3 -4
  36. package/lib/commonjs/components/ScreenContainer.web.js.map +1 -1
  37. package/lib/commonjs/components/ScreenContentWrapper.js +2 -4
  38. package/lib/commonjs/components/ScreenContentWrapper.js.map +1 -1
  39. package/lib/commonjs/components/ScreenContentWrapper.web.js +1 -2
  40. package/lib/commonjs/components/ScreenContentWrapper.web.js.map +1 -1
  41. package/lib/commonjs/components/ScreenFooter.js +2 -8
  42. package/lib/commonjs/components/ScreenFooter.js.map +1 -1
  43. package/lib/commonjs/components/ScreenFooter.web.js +1 -2
  44. package/lib/commonjs/components/ScreenFooter.web.js.map +1 -1
  45. package/lib/commonjs/components/ScreenStack.js +47 -9
  46. package/lib/commonjs/components/ScreenStack.js.map +1 -1
  47. package/lib/commonjs/components/ScreenStack.web.js +2 -1
  48. package/lib/commonjs/components/ScreenStack.web.js.map +1 -1
  49. package/lib/commonjs/components/ScreenStackHeaderConfig.js +10 -10
  50. package/lib/commonjs/components/ScreenStackHeaderConfig.js.map +1 -1
  51. package/lib/commonjs/components/ScreenStackItem.js +99 -0
  52. package/lib/commonjs/components/ScreenStackItem.js.map +1 -0
  53. package/lib/commonjs/components/SearchBar.js +5 -5
  54. package/lib/commonjs/components/SearchBar.js.map +1 -1
  55. package/lib/commonjs/components/SearchBar.web.js +3 -4
  56. package/lib/commonjs/components/SearchBar.web.js.map +1 -1
  57. package/lib/commonjs/contexts.js +11 -0
  58. package/lib/commonjs/contexts.js.map +1 -0
  59. package/lib/commonjs/core.js +0 -3
  60. package/lib/commonjs/core.js.map +1 -1
  61. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  62. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  63. package/lib/commonjs/gesture-handler/GestureDetectorProvider.js +2 -2
  64. package/lib/commonjs/gesture-handler/GestureDetectorProvider.js.map +1 -1
  65. package/lib/commonjs/gesture-handler/ScreenGestureDetector.js +3 -3
  66. package/lib/commonjs/gesture-handler/ScreenGestureDetector.js.map +1 -1
  67. package/lib/commonjs/gesture-handler/fabricUtils.js +54 -18
  68. package/lib/commonjs/gesture-handler/fabricUtils.js.map +1 -1
  69. package/lib/commonjs/index.js +23 -86
  70. package/lib/commonjs/index.js.map +1 -1
  71. package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js +4 -0
  72. package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js.map +1 -1
  73. package/lib/commonjs/native-stack/views/FooterComponent.js +2 -2
  74. package/lib/commonjs/native-stack/views/FooterComponent.js.map +1 -1
  75. package/lib/commonjs/native-stack/views/HeaderConfig.js +10 -8
  76. package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -1
  77. package/lib/commonjs/native-stack/views/NativeStackView.js +34 -39
  78. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  79. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +2 -2
  80. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -1
  81. package/lib/commonjs/reanimated/ReanimatedScreen.js +2 -2
  82. package/lib/commonjs/reanimated/ReanimatedScreen.js.map +1 -1
  83. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +2 -2
  84. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -1
  85. package/lib/commonjs/utils.js +28 -6
  86. package/lib/commonjs/utils.js.map +1 -1
  87. package/lib/module/components/DebugContainer.js +31 -0
  88. package/lib/module/components/DebugContainer.js.map +1 -0
  89. package/lib/module/components/DebugContainer.web.js +6 -0
  90. package/lib/module/components/DebugContainer.web.js.map +1 -0
  91. package/lib/module/components/FullWindowOverlay.js +9 -6
  92. package/lib/module/components/FullWindowOverlay.js.map +1 -1
  93. package/lib/module/components/Screen.js +27 -9
  94. package/lib/module/components/Screen.js.map +1 -1
  95. package/lib/module/components/ScreenContainer.js +2 -4
  96. package/lib/module/components/ScreenContainer.js.map +1 -1
  97. package/lib/module/components/ScreenContainer.web.js +2 -3
  98. package/lib/module/components/ScreenContainer.web.js.map +1 -1
  99. package/lib/module/components/ScreenContentWrapper.js +1 -3
  100. package/lib/module/components/ScreenContentWrapper.js.map +1 -1
  101. package/lib/module/components/ScreenContentWrapper.web.js +0 -1
  102. package/lib/module/components/ScreenContentWrapper.web.js.map +1 -1
  103. package/lib/module/components/ScreenFooter.js +1 -7
  104. package/lib/module/components/ScreenFooter.js.map +1 -1
  105. package/lib/module/components/ScreenFooter.web.js +0 -1
  106. package/lib/module/components/ScreenFooter.web.js.map +1 -1
  107. package/lib/module/components/ScreenStack.js +46 -8
  108. package/lib/module/components/ScreenStack.js.map +1 -1
  109. package/lib/module/components/ScreenStack.web.js +2 -1
  110. package/lib/module/components/ScreenStack.web.js.map +1 -1
  111. package/lib/module/components/ScreenStackHeaderConfig.js +10 -8
  112. package/lib/module/components/ScreenStackHeaderConfig.js.map +1 -1
  113. package/lib/module/components/ScreenStackItem.js +90 -0
  114. package/lib/module/components/ScreenStackItem.js.map +1 -0
  115. package/lib/module/components/SearchBar.js +3 -3
  116. package/lib/module/components/SearchBar.js.map +1 -1
  117. package/lib/module/components/SearchBar.web.js +2 -3
  118. package/lib/module/components/SearchBar.web.js.map +1 -1
  119. package/lib/module/contexts.js +4 -0
  120. package/lib/module/contexts.js.map +1 -0
  121. package/lib/module/core.js +0 -3
  122. package/lib/module/core.js.map +1 -1
  123. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  124. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  125. package/lib/module/gesture-handler/GestureDetectorProvider.js +1 -1
  126. package/lib/module/gesture-handler/GestureDetectorProvider.js.map +1 -1
  127. package/lib/module/gesture-handler/ScreenGestureDetector.js +3 -3
  128. package/lib/module/gesture-handler/ScreenGestureDetector.js.map +1 -1
  129. package/lib/module/gesture-handler/fabricUtils.js +55 -17
  130. package/lib/module/gesture-handler/fabricUtils.js.map +1 -1
  131. package/lib/module/index.js +12 -18
  132. package/lib/module/index.js.map +1 -1
  133. package/lib/module/native-stack/navigators/createNativeStackNavigator.js +4 -0
  134. package/lib/module/native-stack/navigators/createNativeStackNavigator.js.map +1 -1
  135. package/lib/module/native-stack/views/FooterComponent.js +1 -1
  136. package/lib/module/native-stack/views/FooterComponent.js.map +1 -1
  137. package/lib/module/native-stack/views/HeaderConfig.js +3 -1
  138. package/lib/module/native-stack/views/HeaderConfig.js.map +1 -1
  139. package/lib/module/native-stack/views/NativeStackView.js +28 -33
  140. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  141. package/lib/module/reanimated/ReanimatedNativeStackScreen.js +1 -2
  142. package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -1
  143. package/lib/module/reanimated/ReanimatedScreen.js +1 -2
  144. package/lib/module/reanimated/ReanimatedScreen.js.map +1 -1
  145. package/lib/module/reanimated/ReanimatedScreenProvider.js +1 -1
  146. package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -1
  147. package/lib/module/utils.js +26 -5
  148. package/lib/module/utils.js.map +1 -1
  149. package/lib/typescript/components/DebugContainer.d.ts +15 -0
  150. package/lib/typescript/components/DebugContainer.d.ts.map +1 -0
  151. package/lib/typescript/components/DebugContainer.web.d.ts +4 -0
  152. package/lib/typescript/components/DebugContainer.web.d.ts.map +1 -0
  153. package/lib/typescript/components/FullWindowOverlay.d.ts.map +1 -1
  154. package/lib/typescript/components/Screen.d.ts +2 -7
  155. package/lib/typescript/components/Screen.d.ts.map +1 -1
  156. package/lib/typescript/components/Screen.web.d.ts +1 -1
  157. package/lib/typescript/components/Screen.web.d.ts.map +1 -1
  158. package/lib/typescript/components/ScreenContainer.d.ts +1 -3
  159. package/lib/typescript/components/ScreenContainer.d.ts.map +1 -1
  160. package/lib/typescript/components/ScreenContainer.web.d.ts +2 -3
  161. package/lib/typescript/components/ScreenContainer.web.d.ts.map +1 -1
  162. package/lib/typescript/components/ScreenContentWrapper.d.ts +0 -1
  163. package/lib/typescript/components/ScreenContentWrapper.d.ts.map +1 -1
  164. package/lib/typescript/components/ScreenContentWrapper.web.d.ts +0 -1
  165. package/lib/typescript/components/ScreenContentWrapper.web.d.ts.map +1 -1
  166. package/lib/typescript/components/ScreenFooter.d.ts +0 -4
  167. package/lib/typescript/components/ScreenFooter.d.ts.map +1 -1
  168. package/lib/typescript/components/ScreenFooter.web.d.ts +0 -1
  169. package/lib/typescript/components/ScreenFooter.web.d.ts.map +1 -1
  170. package/lib/typescript/components/ScreenStack.d.ts +1 -1
  171. package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
  172. package/lib/typescript/components/ScreenStack.web.d.ts +2 -1
  173. package/lib/typescript/components/ScreenStack.web.d.ts.map +1 -1
  174. package/lib/typescript/components/ScreenStackHeaderConfig.d.ts +3 -3
  175. package/lib/typescript/components/ScreenStackHeaderConfig.d.ts.map +1 -1
  176. package/lib/typescript/components/ScreenStackHeaderConfig.web.d.ts +1 -1
  177. package/lib/typescript/components/ScreenStackHeaderConfig.web.d.ts.map +1 -1
  178. package/lib/typescript/components/ScreenStackItem.d.ts +11 -0
  179. package/lib/typescript/components/ScreenStackItem.d.ts.map +1 -0
  180. package/lib/typescript/components/SearchBar.d.ts +1 -15
  181. package/lib/typescript/components/SearchBar.d.ts.map +1 -1
  182. package/lib/typescript/components/SearchBar.web.d.ts +2 -3
  183. package/lib/typescript/components/SearchBar.web.d.ts.map +1 -1
  184. package/lib/typescript/contexts.d.ts +5 -0
  185. package/lib/typescript/contexts.d.ts.map +1 -0
  186. package/lib/typescript/core.d.ts +0 -1
  187. package/lib/typescript/core.d.ts.map +1 -1
  188. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +9 -3
  189. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  190. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +2 -2
  191. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  192. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +2 -2
  193. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
  194. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts +1 -1
  195. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts.map +1 -1
  196. package/lib/typescript/gesture-handler/ScreenGestureDetector.d.ts +2 -2
  197. package/lib/typescript/gesture-handler/ScreenGestureDetector.d.ts.map +1 -1
  198. package/lib/typescript/gesture-handler/fabricUtils.d.ts +7 -5
  199. package/lib/typescript/gesture-handler/fabricUtils.d.ts.map +1 -1
  200. package/lib/typescript/index.d.ts +10 -16
  201. package/lib/typescript/index.d.ts.map +1 -1
  202. package/lib/typescript/native-stack/navigators/createNativeStackNavigator.d.ts +3 -0
  203. package/lib/typescript/native-stack/navigators/createNativeStackNavigator.d.ts.map +1 -1
  204. package/lib/typescript/native-stack/types.d.ts +58 -12
  205. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  206. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts +1 -1
  207. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts.map +1 -1
  208. package/lib/typescript/native-stack/views/HeaderConfig.d.ts.map +1 -1
  209. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  210. package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +1 -1
  211. package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts.map +1 -1
  212. package/lib/typescript/reanimated/ReanimatedScreen.d.ts +1 -1
  213. package/lib/typescript/reanimated/ReanimatedScreen.d.ts.map +1 -1
  214. package/lib/typescript/reanimated/ReanimatedScreenProvider.d.ts.map +1 -1
  215. package/lib/typescript/types.d.ts +52 -16
  216. package/lib/typescript/types.d.ts.map +1 -1
  217. package/lib/typescript/utils.d.ts +26 -1
  218. package/lib/typescript/utils.d.ts.map +1 -1
  219. package/native-stack/README.md +5 -4
  220. package/native-stack/package.json +4 -4
  221. package/package.json +1 -1
  222. package/react-native.config.js +16 -28
  223. package/src/components/DebugContainer.tsx +47 -0
  224. package/src/components/DebugContainer.web.tsx +7 -0
  225. package/src/components/FullWindowOverlay.tsx +10 -2
  226. package/src/components/Screen.tsx +38 -24
  227. package/src/components/Screen.web.tsx +1 -1
  228. package/src/components/ScreenContainer.tsx +4 -11
  229. package/src/components/ScreenContainer.web.tsx +2 -3
  230. package/src/components/ScreenContentWrapper.tsx +2 -5
  231. package/src/components/ScreenContentWrapper.web.tsx +1 -2
  232. package/src/components/ScreenFooter.tsx +2 -8
  233. package/src/components/ScreenFooter.web.tsx +1 -2
  234. package/src/components/ScreenStack.tsx +99 -12
  235. package/src/components/ScreenStack.web.tsx +3 -1
  236. package/src/components/ScreenStackHeaderConfig.tsx +25 -14
  237. package/src/components/ScreenStackHeaderConfig.web.tsx +1 -1
  238. package/src/components/ScreenStackItem.tsx +162 -0
  239. package/src/components/SearchBar.tsx +4 -7
  240. package/src/components/SearchBar.web.tsx +2 -3
  241. package/src/contexts.tsx +9 -0
  242. package/src/core.ts +0 -3
  243. package/src/fabric/ModalScreenNativeComponent.ts +11 -3
  244. package/src/fabric/ScreenNativeComponent.ts +2 -2
  245. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +2 -1
  246. package/src/fabric/ScreenStackNativeComponent.ts +1 -1
  247. package/src/gesture-handler/GestureDetectorProvider.tsx +2 -2
  248. package/src/gesture-handler/ScreenGestureDetector.tsx +4 -4
  249. package/src/gesture-handler/fabricUtils.ts +74 -27
  250. package/src/index.tsx +11 -37
  251. package/src/native-stack/navigators/createNativeStackNavigator.tsx +3 -0
  252. package/src/native-stack/types.tsx +60 -17
  253. package/src/native-stack/utils/getDefaultHeaderHeight.tsx +1 -1
  254. package/src/native-stack/views/FooterComponent.tsx +1 -1
  255. package/src/native-stack/views/HeaderConfig.tsx +7 -5
  256. package/src/native-stack/views/NativeStackView.tsx +48 -67
  257. package/src/reanimated/ReanimatedNativeStackScreen.tsx +2 -2
  258. package/src/reanimated/ReanimatedScreen.tsx +2 -1
  259. package/src/reanimated/ReanimatedScreenProvider.tsx +2 -1
  260. package/src/types.tsx +72 -15
  261. package/src/utils.ts +27 -5
@@ -38,25 +38,34 @@ target_include_directories(
38
38
  ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}
39
39
  )
40
40
 
41
- target_link_libraries(
42
- ${LIB_TARGET_NAME}
43
- fbjni
44
- folly_runtime
45
- glog
46
- jsi
47
- react_codegen_rncore
48
- react_debug
49
- react_nativemodule_core
50
- react_render_core
51
- react_render_debug
52
- react_render_graphics
53
- react_render_mapbuffer
54
- react_render_componentregistry
55
- react_utils
56
- rrc_view
57
- turbomodulejsijni
58
- yoga
59
- )
41
+ if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
42
+ target_link_libraries(
43
+ ${LIB_TARGET_NAME}
44
+ ReactAndroid::reactnative
45
+ ReactAndroid::jsi
46
+ fbjni::fbjni
47
+ )
48
+ else()
49
+ target_link_libraries(
50
+ ${LIB_TARGET_NAME}
51
+ fbjni
52
+ folly_runtime
53
+ glog
54
+ jsi
55
+ react_codegen_rncore
56
+ react_debug
57
+ react_nativemodule_core
58
+ react_render_core
59
+ react_render_debug
60
+ react_render_graphics
61
+ react_render_mapbuffer
62
+ react_render_componentregistry
63
+ react_utils
64
+ rrc_view
65
+ turbomodulejsijni
66
+ yoga
67
+ )
68
+ endif()
60
69
 
61
70
  target_compile_options(
62
71
  ${LIB_TARGET_NAME}
@@ -52,7 +52,7 @@ public class RNSScreenManagerDelegate<T extends View, U extends BaseViewManagerI
52
52
  mViewManager.setFullScreenSwipeEnabled(view, value == null ? false : (boolean) value);
53
53
  break;
54
54
  case "fullScreenSwipeShadowEnabled":
55
- mViewManager.setFullScreenSwipeShadowEnabled(view, value == null ? false : (boolean) value);
55
+ mViewManager.setFullScreenSwipeShadowEnabled(view, value == null ? true : (boolean) value);
56
56
  break;
57
57
  case "homeIndicatorHidden":
58
58
  mViewManager.setHomeIndicatorHidden(view, value == null ? false : (boolean) value);
@@ -91,7 +91,7 @@ public class RNSScreenManagerDelegate<T extends View, U extends BaseViewManagerI
91
91
  mViewManager.setStackAnimation(view, (String) value);
92
92
  break;
93
93
  case "transitionDuration":
94
- mViewManager.setTransitionDuration(view, value == null ? 350 : ((Double) value).intValue());
94
+ mViewManager.setTransitionDuration(view, value == null ? 500 : ((Double) value).intValue());
95
95
  break;
96
96
  case "replaceAnimation":
97
97
  mViewManager.setReplaceAnimation(view, (String) value);
package/ios/RNSConvert.h CHANGED
@@ -1,12 +1,17 @@
1
- #ifdef RCT_NEW_ARCH_ENABLED
2
1
  #import <UIKit/UIKit.h>
2
+ #ifdef RCT_NEW_ARCH_ENABLED
3
3
  #import <react/renderer/components/rnscreens/Props.h>
4
+ #endif // RCT_NEW_ARCH_ENABLED
4
5
  #import "RNSEnums.h"
5
6
 
7
+ #ifdef RCT_NEW_ARCH_ENABLED
6
8
  namespace react = facebook::react;
9
+ #endif // RCT_NEW_ARCH_ENABLED
7
10
 
8
11
  @interface RNSConvert : NSObject
9
12
 
13
+ #ifdef RCT_NEW_ARCH_ENABLED
14
+
10
15
  + (UISemanticContentAttribute)UISemanticContentAttributeFromCppEquivalent:
11
16
  (react::RNSScreenStackHeaderConfigDirection)direction;
12
17
 
@@ -42,8 +47,12 @@ namespace react = facebook::react;
42
47
 
43
48
  + (NSMutableArray<NSNumber *> *)arrayFromVector:(const std::vector<CGFloat> &)vector;
44
49
 
45
- + (UIBlurEffectStyle)UIBlurEffectStyleFromCppEquivalent:(react::RNSScreenStackHeaderConfigBlurEffect)blurEffect;
46
-
47
- @end
50
+ + (RNSBlurEffectStyle)RNSBlurEffectStyleFromCppEquivalent:(react::RNSScreenStackHeaderConfigBlurEffect)blurEffect;
48
51
 
49
52
  #endif // RCT_NEW_ARCH_ENABLED
53
+
54
+ /// This method fails (by assertion) when `blurEffect == RNSBlurEffectStyleNone` which has no counter part in the UIKit
55
+ /// type.
56
+ + (UIBlurEffectStyle)tryConvertRNSBlurEffectStyleToUIBlurEffectStyle:(RNSBlurEffectStyle)blurEffect;
57
+
58
+ @end
package/ios/RNSConvert.mm CHANGED
@@ -1,8 +1,12 @@
1
1
  #import "RNSConvert.h"
2
2
 
3
- #ifdef RCT_NEW_ARCH_ENABLED
3
+ #ifndef RCT_NEW_ARCH_ENABLED
4
+ #import <React/RCTAssert.h>
5
+ #endif // !RCT_NEW_ARCH_ENABLED
6
+
4
7
  @implementation RNSConvert
5
8
 
9
+ #ifdef RCT_NEW_ARCH_ENABLED
6
10
  + (UISemanticContentAttribute)UISemanticContentAttributeFromCppEquivalent:
7
11
  (react::RNSScreenStackHeaderConfigDirection)direction
8
12
  {
@@ -173,71 +177,89 @@
173
177
  return array;
174
178
  }
175
179
 
176
- + (UIBlurEffectStyle)UIBlurEffectStyleFromCppEquivalent:(react::RNSScreenStackHeaderConfigBlurEffect)blurEffect
180
+ + (RNSBlurEffectStyle)RNSBlurEffectStyleFromCppEquivalent:(react::RNSScreenStackHeaderConfigBlurEffect)blurEffect
177
181
  {
178
182
  #if !TARGET_OS_TV && defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
179
183
  __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
180
184
  if (@available(iOS 13.0, *)) {
181
185
  switch (blurEffect) {
186
+ case react::RNSScreenStackHeaderConfigBlurEffect::None:
187
+ return RNSBlurEffectStyleNone;
182
188
  case react::RNSScreenStackHeaderConfigBlurEffect::ExtraLight:
183
- return UIBlurEffectStyleExtraLight;
189
+ return RNSBlurEffectStyleExtraLight;
184
190
  case react::RNSScreenStackHeaderConfigBlurEffect::Light:
185
- return UIBlurEffectStyleLight;
191
+ return RNSBlurEffectStyleLight;
186
192
  case react::RNSScreenStackHeaderConfigBlurEffect::Dark:
187
- return UIBlurEffectStyleDark;
193
+ return RNSBlurEffectStyleDark;
188
194
  case react::RNSScreenStackHeaderConfigBlurEffect::Regular:
189
- return UIBlurEffectStyleRegular;
195
+ return RNSBlurEffectStyleRegular;
190
196
  case react::RNSScreenStackHeaderConfigBlurEffect::Prominent:
191
- return UIBlurEffectStyleProminent;
197
+ return RNSBlurEffectStyleProminent;
192
198
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemUltraThinMaterial:
193
- return UIBlurEffectStyleSystemUltraThinMaterial;
199
+ return RNSBlurEffectStyleSystemUltraThinMaterial;
194
200
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThinMaterial:
195
- return UIBlurEffectStyleSystemThinMaterial;
201
+ return RNSBlurEffectStyleSystemThinMaterial;
196
202
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemMaterial:
197
- return UIBlurEffectStyleSystemMaterial;
203
+ return RNSBlurEffectStyleSystemMaterial;
198
204
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThickMaterial:
199
- return UIBlurEffectStyleSystemThickMaterial;
205
+ return RNSBlurEffectStyleSystemThickMaterial;
200
206
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemChromeMaterial:
201
- return UIBlurEffectStyleSystemChromeMaterial;
207
+ return RNSBlurEffectStyleSystemChromeMaterial;
202
208
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemUltraThinMaterialLight:
203
- return UIBlurEffectStyleSystemUltraThinMaterialLight;
209
+ return RNSBlurEffectStyleSystemUltraThinMaterialLight;
204
210
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThinMaterialLight:
205
- return UIBlurEffectStyleSystemThinMaterialLight;
211
+ return RNSBlurEffectStyleSystemThinMaterialLight;
206
212
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemMaterialLight:
207
- return UIBlurEffectStyleSystemMaterialLight;
213
+ return RNSBlurEffectStyleSystemMaterialLight;
208
214
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThickMaterialLight:
209
- return UIBlurEffectStyleSystemThickMaterialLight;
215
+ return RNSBlurEffectStyleSystemThickMaterialLight;
210
216
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemChromeMaterialLight:
211
- return UIBlurEffectStyleSystemChromeMaterialLight;
217
+ return RNSBlurEffectStyleSystemChromeMaterialLight;
212
218
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemUltraThinMaterialDark:
213
- return UIBlurEffectStyleSystemUltraThinMaterialDark;
219
+ return RNSBlurEffectStyleSystemUltraThinMaterialDark;
214
220
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThinMaterialDark:
215
- return UIBlurEffectStyleSystemThinMaterialDark;
221
+ return RNSBlurEffectStyleSystemThinMaterialDark;
216
222
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemMaterialDark:
217
- return UIBlurEffectStyleSystemMaterialDark;
223
+ return RNSBlurEffectStyleSystemMaterialDark;
218
224
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemThickMaterialDark:
219
- return UIBlurEffectStyleSystemThickMaterialDark;
225
+ return RNSBlurEffectStyleSystemThickMaterialDark;
220
226
  case react::RNSScreenStackHeaderConfigBlurEffect::SystemChromeMaterialDark:
221
- return UIBlurEffectStyleSystemChromeMaterialDark;
227
+ return RNSBlurEffectStyleSystemChromeMaterialDark;
222
228
  }
223
229
  }
224
230
  #endif
225
231
 
226
232
  switch (blurEffect) {
233
+ case react::RNSScreenStackHeaderConfigBlurEffect::None:
234
+ return RNSBlurEffectStyleNone;
227
235
  case react::RNSScreenStackHeaderConfigBlurEffect::Light:
228
- return UIBlurEffectStyleLight;
236
+ return RNSBlurEffectStyleLight;
229
237
  case react::RNSScreenStackHeaderConfigBlurEffect::Dark:
230
- return UIBlurEffectStyleDark;
238
+ return RNSBlurEffectStyleDark;
231
239
  case react::RNSScreenStackHeaderConfigBlurEffect::Regular:
232
- return UIBlurEffectStyleRegular;
240
+ return RNSBlurEffectStyleRegular;
233
241
  case react::RNSScreenStackHeaderConfigBlurEffect::Prominent:
234
- return UIBlurEffectStyleProminent;
242
+ return RNSBlurEffectStyleProminent;
235
243
  case react::RNSScreenStackHeaderConfigBlurEffect::ExtraLight:
236
244
  default:
237
- return UIBlurEffectStyleExtraLight;
245
+ return RNSBlurEffectStyleNone;
238
246
  }
239
247
  }
240
248
 
241
- @end
249
+ #endif // RCT_NEW_ARCH_ENABLED
242
250
 
251
+ + (UIBlurEffectStyle)tryConvertRNSBlurEffectStyleToUIBlurEffectStyle:(RNSBlurEffectStyle)blurEffect
252
+ {
253
+ #ifdef RCT_NEW_ARCH_ENABLED
254
+ react_native_assert(blurEffect != RNSBlurEffectStyleNone);
255
+ #else
256
+ RCTAssert(
257
+ blurEffect != RNSBlurEffectStyleNone, @"RNSBlurEffectStyleNone variant is not convertible to UIBlurEffectStyle");
243
258
  #endif // RCT_NEW_ARCH_ENABLED
259
+
260
+ // Cast safety: RNSBlurEffectStyle is defined in such way that its values map 1:1 with
261
+ // UIBlurEffectStyle, except RNSBlurEffectStyleNone which is excluded above.
262
+ return (UIBlurEffectStyle)blurEffect;
263
+ }
264
+
265
+ @end
package/ios/RNSEnums.h CHANGED
@@ -30,6 +30,7 @@ typedef NS_ENUM(NSInteger, RNSScreenSwipeDirection) {
30
30
  };
31
31
 
32
32
  typedef NS_ENUM(NSInteger, RNSActivityState) {
33
+ RNSActivityStateUndefined = -1,
33
34
  RNSActivityStateInactive = 0,
34
35
  RNSActivityStateTransitioningOrBelowTop = 1,
35
36
  RNSActivityStateOnTop = 2
@@ -70,3 +71,49 @@ typedef NS_ENUM(NSInteger, RNSSearchBarPlacement) {
70
71
  RNSSearchBarPlacementInline,
71
72
  RNSSearchBarPlacementStacked,
72
73
  };
74
+
75
+ // Redefinition of UIBlurEffectStyle. We need to represent additional case of `None`.
76
+ typedef NS_ENUM(NSInteger, RNSBlurEffectStyle) {
77
+ /// No blur effect should be visible
78
+ RNSBlurEffectStyleNone = -1,
79
+ RNSBlurEffectStyleExtraLight = UIBlurEffectStyleExtraLight,
80
+ RNSBlurEffectStyleLight = UIBlurEffectStyleLight,
81
+ RNSBlurEffectStyleDark = UIBlurEffectStyleDark,
82
+ // TODO: Add support for this variant on tvOS
83
+ // RNSBlurEffectStyleExtraDark = UIBlurEffectStyleExtraDark API_AVAILABLE(tvos(10.0)) API_UNAVAILABLE(ios)
84
+ // API_UNAVAILABLE(watchos),
85
+ RNSBlurEffectStyleRegular API_AVAILABLE(ios(10.0)) API_UNAVAILABLE(watchos) = UIBlurEffectStyleRegular,
86
+ RNSBlurEffectStyleProminent API_AVAILABLE(ios(10.0)) API_UNAVAILABLE(watchos) = UIBlurEffectStyleProminent,
87
+ RNSBlurEffectStyleSystemUltraThinMaterial API_AVAILABLE(ios(13.0))
88
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemUltraThinMaterial,
89
+ RNSBlurEffectStyleSystemThinMaterial API_AVAILABLE(ios(13.0))
90
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThinMaterial,
91
+ RNSBlurEffectStyleSystemMaterial API_AVAILABLE(ios(13.0))
92
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemMaterial,
93
+ RNSBlurEffectStyleSystemThickMaterial API_AVAILABLE(ios(13.0))
94
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThickMaterial,
95
+ RNSBlurEffectStyleSystemChromeMaterial API_AVAILABLE(ios(13.0))
96
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemChromeMaterial,
97
+ RNSBlurEffectStyleSystemUltraThinMaterialLight API_AVAILABLE(ios(13.0))
98
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemUltraThinMaterialLight,
99
+ RNSBlurEffectStyleSystemThinMaterialLight API_AVAILABLE(ios(13.0))
100
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThinMaterialLight,
101
+ RNSBlurEffectStyleSystemMaterialLight API_AVAILABLE(ios(13.0))
102
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemMaterialLight,
103
+ RNSBlurEffectStyleSystemThickMaterialLight API_AVAILABLE(ios(13.0))
104
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThickMaterialLight,
105
+ RNSBlurEffectStyleSystemChromeMaterialLight API_AVAILABLE(ios(13.0))
106
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemChromeMaterialLight,
107
+
108
+ RNSBlurEffectStyleSystemUltraThinMaterialDark API_AVAILABLE(ios(13.0))
109
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemUltraThinMaterialDark,
110
+ RNSBlurEffectStyleSystemThinMaterialDark API_AVAILABLE(ios(13.0))
111
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThinMaterialDark,
112
+ RNSBlurEffectStyleSystemMaterialDark API_AVAILABLE(ios(13.0))
113
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemMaterialDark,
114
+ RNSBlurEffectStyleSystemThickMaterialDark API_AVAILABLE(ios(13.0))
115
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemThickMaterialDark,
116
+ RNSBlurEffectStyleSystemChromeMaterialDark API_AVAILABLE(ios(13.0))
117
+ API_UNAVAILABLE(watchos, tvos) = UIBlurEffectStyleSystemChromeMaterialDark
118
+
119
+ } API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(watchos);
@@ -0,0 +1,12 @@
1
+ #import <UIKit/UIKit.h>
2
+ #import "RNSScreenStackAnimator.h"
3
+
4
+ NS_ASSUME_NONNULL_BEGIN
5
+
6
+ @interface RNSPercentDrivenInteractiveTransition : UIPercentDrivenInteractiveTransition
7
+
8
+ @property (nonatomic, nullable) RNSScreenStackAnimator *animationController;
9
+
10
+ @end
11
+
12
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,69 @@
1
+ #import "RNSPercentDrivenInteractiveTransition.h"
2
+
3
+ @implementation RNSPercentDrivenInteractiveTransition {
4
+ RNSScreenStackAnimator *_animationController;
5
+ }
6
+
7
+ #pragma mark - UIViewControllerInteractiveTransitioning
8
+
9
+ - (void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext
10
+ {
11
+ [super startInteractiveTransition:transitionContext];
12
+ }
13
+
14
+ #pragma mark - UIPercentDrivenInteractiveTransition
15
+
16
+ // `updateInteractiveTransition`, `finishInteractiveTransition`,
17
+ // `cancelInteractiveTransition` are forwared by superclass to
18
+ // corresponding methods in transition context. In case
19
+ // of "classical CA driven animations", such as UIView animation blocks
20
+ // or direct utilization of CoreAnimation API, context drives the animation,
21
+ // however in case of UIViewPropertyAnimator it does not. We need
22
+ // to drive animation manually and this is exactly what happens below.
23
+
24
+ - (void)updateInteractiveTransition:(CGFloat)percentComplete
25
+ {
26
+ if (_animationController != nil) {
27
+ [_animationController.inFlightAnimator setFractionComplete:percentComplete];
28
+ }
29
+ [super updateInteractiveTransition:percentComplete];
30
+ }
31
+
32
+ - (void)finishInteractiveTransition
33
+ {
34
+ [self finalizeInteractiveTransitionWithAnimationWasCancelled:NO];
35
+ [super finishInteractiveTransition];
36
+ }
37
+
38
+ - (void)cancelInteractiveTransition
39
+ {
40
+ [self finalizeInteractiveTransitionWithAnimationWasCancelled:YES];
41
+ [super cancelInteractiveTransition];
42
+ }
43
+
44
+ #pragma mark - Helpers
45
+
46
+ - (void)finalizeInteractiveTransitionWithAnimationWasCancelled:(BOOL)cancelled
47
+ {
48
+ if (_animationController == nil) {
49
+ return;
50
+ }
51
+
52
+ UIViewPropertyAnimator *_Nullable animator = _animationController.inFlightAnimator;
53
+ if (animator == nil) {
54
+ return;
55
+ }
56
+
57
+ BOOL shouldReverseAnimation = cancelled;
58
+
59
+ id<UITimingCurveProvider> timingParams = [_animationController timingParamsForAnimationCompletion];
60
+
61
+ [animator pauseAnimation];
62
+ [animator setReversed:shouldReverseAnimation];
63
+ [animator continueAnimationWithTimingParameters:timingParams durationFactor:(1 - animator.fractionComplete)];
64
+
65
+ // System retains it & we don't need it anymore.
66
+ _animationController = nil;
67
+ }
68
+
69
+ @end
package/ios/RNSScreen.h CHANGED
@@ -100,6 +100,8 @@ namespace react = facebook::react;
100
100
  @property (nonatomic) react::LayoutMetrics newLayoutMetrics;
101
101
  @property (weak, nonatomic) RNSScreenStackHeaderConfig *config;
102
102
  @property (nonatomic, readonly) BOOL hasHeaderConfig;
103
+ @property (nonatomic, readonly, getter=isMarkedForUnmountInCurrentTransaction)
104
+ BOOL markedForUnmountInCurrentTransaction;
103
105
  #else
104
106
  @property (nonatomic, copy) RCTDirectEventBlock onAppear;
105
107
  @property (nonatomic, copy) RCTDirectEventBlock onDisappear;
@@ -124,6 +126,10 @@ namespace react = facebook::react;
124
126
  - (void)updateBounds;
125
127
  - (void)notifyDismissedWithCount:(int)dismissCount;
126
128
  - (instancetype)initWithFrame:(CGRect)frame;
129
+ /// Tell `Screen` that it will be unmounted in next transaction.
130
+ /// The component needs this so that we can later decide whether to
131
+ /// replace it with snapshot or not.
132
+ - (void)willBeUnmountedInUpcomingTransaction;
127
133
  #else
128
134
  - (instancetype)initWithBridge:(RCTBridge *)bridge;
129
135
  #endif // RCT_NEW_ARCH_ENABLED
@@ -133,6 +139,14 @@ namespace react = facebook::react;
133
139
  - (BOOL)isModal;
134
140
  - (BOOL)isPresentedAsNativeModal;
135
141
 
142
+ /**
143
+ * Tell `Screen` component that it has been removed from react state and can safely cleanup
144
+ * any retained resources.
145
+ *
146
+ * Note, that on old architecture this method might be called by RN via `RCTInvalidating` protocol.
147
+ */
148
+ - (void)invalidate;
149
+
136
150
  /// Looks for header configuration in instance's `reactSubviews` and returns it. If not present returns `nil`.
137
151
  - (RNSScreenStackHeaderConfig *_Nullable)findHeaderConfig;
138
152
 
package/ios/RNSScreen.mm CHANGED
@@ -118,11 +118,16 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
118
118
  _hasStatusBarHiddenSet = NO;
119
119
  _hasOrientationSet = NO;
120
120
  _hasHomeIndicatorHiddenSet = NO;
121
+ _activityState = RNSActivityStateUndefined;
122
+ _fullScreenSwipeShadowEnabled = YES;
121
123
  #if !TARGET_OS_TV
122
124
  _sheetExpandsWhenScrolledToEdge = YES;
123
125
  #endif // !TARGET_OS_TV
124
126
  _sheetsScrollView = nil;
125
127
  _didSetSheetAllowedDetentsOnController = NO;
128
+ #ifdef RCT_NEW_ARCH_ENABLED
129
+ _markedForUnmountInCurrentTransaction = NO;
130
+ #endif // RCT_NEW_ARCH_ENABLED
126
131
  }
127
132
 
128
133
  - (UIViewController *)reactViewController
@@ -304,15 +309,25 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
304
309
  {
305
310
  int activityState = [activityStateOrNil intValue];
306
311
  if (activityStateOrNil != nil && activityState != -1 && activityState != _activityState) {
307
- if ([_controller.navigationController isKindOfClass:RNSNavigationController.class] &&
308
- _activityState < activityState) {
309
- RCTLogError(@"[RNScreens] activityState can only progress in NativeStack");
310
- }
312
+ [self maybeAssertActivityStateProgressionOldValue:_activityState newValue:activityState];
311
313
  _activityState = activityState;
312
314
  [_reactSuperview markChildUpdated];
313
315
  }
314
316
  }
315
317
 
318
+ - (void)maybeAssertActivityStateProgressionOldValue:(int)oldValue newValue:(int)newValue
319
+ {
320
+ if (self.isNativeStackScreen && newValue < oldValue) {
321
+ RCTLogError(@"[RNScreens] activityState can only progress in NativeStack");
322
+ }
323
+ }
324
+
325
+ /// Note that this method works only after the screen is actually mounted under a screen stack view.
326
+ - (BOOL)isNativeStackScreen
327
+ {
328
+ return [_reactSuperview isKindOfClass:RNSScreenStackView.class];
329
+ }
330
+
316
331
  #if !TARGET_OS_TV && !TARGET_OS_VISION
317
332
  - (void)setStatusBarStyle:(RNSStatusBarStyle)statusBarStyle
318
333
  {
@@ -749,6 +764,12 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
749
764
  self.controller.modalPresentationStyle == UIModalPresentationOverCurrentContext;
750
765
  }
751
766
 
767
+ - (void)invalidate
768
+ {
769
+ _controller = nil;
770
+ [_sheetsScrollView removeObserver:self forKeyPath:@"bounds" context:nil];
771
+ }
772
+
752
773
  #if !TARGET_OS_TV && !TARGET_OS_VISION
753
774
 
754
775
  - (void)setPropertyForSheet:(UISheetPresentationController *)sheet
@@ -1076,6 +1097,11 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
1076
1097
  return _config != nil;
1077
1098
  }
1078
1099
 
1100
+ - (void)willBeUnmountedInUpcomingTransaction
1101
+ {
1102
+ _markedForUnmountInCurrentTransaction = YES;
1103
+ }
1104
+
1079
1105
  + (react::ComponentDescriptorProvider)componentDescriptorProvider
1080
1106
  {
1081
1107
  return react::concreteComponentDescriptorProvider<react::RNSScreenComponentDescriptor>();
@@ -1265,11 +1291,6 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
1265
1291
  // subviews
1266
1292
  }
1267
1293
 
1268
- - (void)invalidate
1269
- {
1270
- _controller = nil;
1271
- [_sheetsScrollView removeObserver:self forKeyPath:@"bounds" context:nil];
1272
- }
1273
1294
  #endif
1274
1295
 
1275
1296
  @end
@@ -20,6 +20,7 @@
20
20
  #import "RCTTouchHandler+RNSUtility.h"
21
21
  #endif // RCT_NEW_ARCH_ENABLED
22
22
 
23
+ #import "RNSPercentDrivenInteractiveTransition.h"
23
24
  #import "RNSScreen.h"
24
25
  #import "RNSScreenStack.h"
25
26
  #import "RNSScreenStackAnimator.h"
@@ -149,9 +150,16 @@ namespace react = facebook::react;
149
150
  NSMutableArray<RNSScreenView *> *_reactSubviews;
150
151
  BOOL _invalidated;
151
152
  BOOL _isFullWidthSwiping;
152
- UIPercentDrivenInteractiveTransition *_interactionController;
153
+ RNSPercentDrivenInteractiveTransition *_interactionController;
153
154
  __weak RNSScreenStackManager *_manager;
154
155
  BOOL _updateScheduled;
156
+ #ifdef RCT_NEW_ARCH_ENABLED
157
+ /// Screens that are subject of `ShadowViewMutation::Type::Delete` mutation
158
+ /// in current transaction. This vector should be populated when we receive notification via
159
+ /// `RCTMountingObserving` protocol, that a transaction will be performed, and should
160
+ /// be cleaned up when we're notified that the transaction has been completed.
161
+ std::vector<__strong RNSScreenView *> _toBeDeletedScreens;
162
+ #endif // RCT_NEW_ARCH_ENABLED
155
163
  }
156
164
 
157
165
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -862,7 +870,7 @@ namespace react = facebook::react;
862
870
 
863
871
  switch (gestureRecognizer.state) {
864
872
  case UIGestureRecognizerStateBegan: {
865
- _interactionController = [UIPercentDrivenInteractiveTransition new];
873
+ _interactionController = [RNSPercentDrivenInteractiveTransition new];
866
874
  [_controller popViewControllerAnimated:YES];
867
875
  break;
868
876
  }
@@ -909,7 +917,7 @@ namespace react = facebook::react;
909
917
  if (_interactionController == nil && fromView.reactSuperview) {
910
918
  BOOL shouldCancelDismiss = [self shouldCancelDismissFromView:fromView toView:toView];
911
919
  if (shouldCancelDismiss) {
912
- _interactionController = [UIPercentDrivenInteractiveTransition new];
920
+ _interactionController = [RNSPercentDrivenInteractiveTransition new];
913
921
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
914
922
  [self->_interactionController cancelInteractiveTransition];
915
923
  self->_interactionController = nil;
@@ -922,6 +930,10 @@ namespace react = facebook::react;
922
930
  });
923
931
  }
924
932
  }
933
+
934
+ if (_interactionController != nil) {
935
+ [_interactionController setAnimationController:animationController];
936
+ }
925
937
  return _interactionController;
926
938
  }
927
939
 
@@ -946,7 +958,7 @@ namespace react = facebook::react;
946
958
 
947
959
  - (void)markChildUpdated
948
960
  {
949
- // do nothing
961
+ // In native stack this should be called only for `preload` purposes.
950
962
  [self updateContainer];
951
963
  }
952
964
 
@@ -1104,7 +1116,7 @@ namespace react = facebook::react;
1104
1116
  {
1105
1117
  if (_interactionController == nil) {
1106
1118
  _customAnimation = YES;
1107
- _interactionController = [UIPercentDrivenInteractiveTransition new];
1119
+ _interactionController = [RNSPercentDrivenInteractiveTransition new];
1108
1120
  [_controller popViewControllerAnimated:YES];
1109
1121
  }
1110
1122
  }
@@ -1151,6 +1163,16 @@ namespace react = facebook::react;
1151
1163
  // `- [RNSScreenStackView mountingTransactionDidMount: withSurfaceTelemetry:]`
1152
1164
  }
1153
1165
 
1166
+ - (nullable RNSScreenView *)childScreenForTag:(react::Tag)tag
1167
+ {
1168
+ for (RNSScreenView *child in _reactSubviews) {
1169
+ if (child.tag == tag) {
1170
+ return child;
1171
+ }
1172
+ }
1173
+ return nil;
1174
+ }
1175
+
1154
1176
  - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
1155
1177
  {
1156
1178
  RNSScreenView *screenChildComponent = (RNSScreenView *)childComponentView;
@@ -1184,6 +1206,20 @@ namespace react = facebook::react;
1184
1206
  [screenChildComponent removeFromSuperview];
1185
1207
  }
1186
1208
 
1209
+ - (void)mountingTransactionWillMount:(const facebook::react::MountingTransaction &)transaction
1210
+ withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry
1211
+ {
1212
+ for (const auto &mutation : transaction.getMutations()) {
1213
+ if (mutation.type == react::ShadowViewMutation::Delete) {
1214
+ RNSScreenView *_Nullable toBeRemovedChild = [self childScreenForTag:mutation.oldChildShadowView.tag];
1215
+ if (toBeRemovedChild != nil) {
1216
+ [toBeRemovedChild willBeUnmountedInUpcomingTransaction];
1217
+ _toBeDeletedScreens.push_back(toBeRemovedChild);
1218
+ }
1219
+ }
1220
+ }
1221
+ }
1222
+
1187
1223
  - (void)mountingTransactionDidMount:(const facebook::react::MountingTransaction &)transaction
1188
1224
  withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry
1189
1225
  {
@@ -1200,6 +1236,21 @@ namespace react = facebook::react;
1200
1236
  break;
1201
1237
  }
1202
1238
  }
1239
+
1240
+ if (!self->_toBeDeletedScreens.empty()) {
1241
+ __weak RNSScreenStackView *weakSelf = self;
1242
+ // We want to run after container updates are performed (transitions etc.)
1243
+ dispatch_async(dispatch_get_main_queue(), ^{
1244
+ RNSScreenStackView *_Nullable strongSelf = weakSelf;
1245
+ if (strongSelf == nil) {
1246
+ return;
1247
+ }
1248
+ for (RNSScreenView *screenRef : strongSelf->_toBeDeletedScreens) {
1249
+ [screenRef invalidate];
1250
+ }
1251
+ strongSelf->_toBeDeletedScreens.clear();
1252
+ });
1253
+ }
1203
1254
  }
1204
1255
 
1205
1256
  - (void)prepareForRecycle
@@ -1227,12 +1278,25 @@ namespace react = facebook::react;
1227
1278
  - (void)invalidate
1228
1279
  {
1229
1280
  _invalidated = YES;
1230
- for (UIViewController *controller in _presentedModals) {
1281
+ [self dismissAllRelatedModals];
1282
+ [_controller willMoveToParentViewController:nil];
1283
+ [_controller removeFromParentViewController];
1284
+ }
1285
+
1286
+ // This method aims to dismiss all modals for which presentation process
1287
+ // has been initiated in this navigation controller, i. e. either a Screen
1288
+ // with modal presentation or foreign modal presented from inside a Screen.
1289
+ - (void)dismissAllRelatedModals
1290
+ {
1291
+ [_controller dismissViewControllerAnimated:NO completion:nil];
1292
+
1293
+ // This loop seems to be excessive. Above message send to `_controller` should
1294
+ // be enough, because system dismisses the controllers recursively,
1295
+ // however better safe than sorry & introduce a regression, thus it is left here.
1296
+ for (UIViewController *controller in [_presentedModals reverseObjectEnumerator]) {
1231
1297
  [controller dismissViewControllerAnimated:NO completion:nil];
1232
1298
  }
1233
1299
  [_presentedModals removeAllObjects];
1234
- [_controller willMoveToParentViewController:nil];
1235
- [_controller removeFromParentViewController];
1236
1300
  }
1237
1301
 
1238
1302
  #endif // RCT_NEW_ARCH_ENABLED
@@ -2,7 +2,19 @@
2
2
 
3
3
  @interface RNSScreenStackAnimator : NSObject <UIViewControllerAnimatedTransitioning>
4
4
 
5
- - (instancetype)initWithOperation:(UINavigationControllerOperation)operation;
5
+ /// This property is filled whenever there is an ongoing animation and cleared on animation end.
6
+ @property (nonatomic, strong, nullable, readonly) UIViewPropertyAnimator *inFlightAnimator;
7
+
8
+ - (nonnull instancetype)initWithOperation:(UINavigationControllerOperation)operation;
9
+
10
+ /// In case of interactive / interruptible transition (e.g. swipe back gesture) this method should return
11
+ /// timing parameters expected by animator to be used for animation completion (e.g. when user's
12
+ /// gesture had ended).
13
+ ///
14
+ /// @return timing curve provider expected to be used for animation completion or nil,
15
+ /// when there is no interactive transition running.
16
+ - (nullable id<UITimingCurveProvider>)timingParamsForAnimationCompletion;
17
+
6
18
  + (BOOL)isCustomAnimation:(RNSScreenStackAnimation)animation;
7
19
 
8
20
  @end