react-native-screens 3.31.1 → 3.33.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 (203) hide show
  1. package/README.md +21 -11
  2. package/RNScreens.podspec +11 -52
  3. package/android/CMakeLists.txt +48 -4
  4. package/android/build.gradle +16 -9
  5. package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +25 -16
  6. package/android/src/fabric/java/com/swmansion/rnscreens/NativeProxy.kt +53 -0
  7. package/android/src/main/cpp/NativeProxy.cpp +51 -0
  8. package/android/src/main/cpp/NativeProxy.h +35 -0
  9. package/android/src/main/cpp/OnLoad.cpp +8 -0
  10. package/android/src/main/cpp/jni-adapter.cpp +86 -93
  11. package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +7 -2
  12. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +6 -1
  13. package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +2 -2
  14. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +36 -17
  15. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +150 -40
  16. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +52 -30
  17. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +27 -4
  18. package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +10 -2
  19. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +56 -27
  20. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +8 -1
  21. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +50 -19
  22. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +63 -39
  23. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +4 -0
  24. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +88 -57
  25. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +131 -36
  26. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +19 -4
  27. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +16 -10
  28. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +28 -25
  29. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +177 -77
  30. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +77 -25
  31. package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +31 -9
  32. package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +3 -1
  33. package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +160 -54
  34. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +29 -22
  35. package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +7 -2
  36. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +4 -1
  37. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +4 -1
  38. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +4 -1
  39. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +5 -6
  40. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +4 -1
  41. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +4 -1
  42. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +8 -4
  43. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +7 -6
  44. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +4 -1
  45. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +4 -1
  46. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +5 -2
  47. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +4 -3
  48. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +4 -1
  49. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +5 -2
  50. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +4 -1
  51. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +9 -4
  52. package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +4 -1
  53. package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +1 -5
  54. package/android/src/main/java/com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper.kt +214 -0
  55. package/android/src/main/jni/CMakeLists.txt +5 -4
  56. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContainerManagerDelegate.java +25 -0
  57. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenContainerManagerInterface.java +16 -0
  58. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +6 -0
  59. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +2 -0
  60. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +3 -0
  61. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +1 -0
  62. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSSearchBarManagerDelegate.java +99 -0
  63. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSSearchBarManagerInterface.java +37 -0
  64. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -5
  65. package/android/src/paper/java/com/swmansion/rnscreens/NativeProxy.kt +19 -0
  66. package/android/src/paper/java/com/swmansion/rnscreens/NativeScreensModuleSpec.java +4 -0
  67. package/common/cpp/react/renderer/components/rnscreens/FrameCorrectionModes.h +51 -0
  68. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenComponentDescriptor.h +8 -9
  69. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.cpp +2 -1
  70. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.h +9 -8
  71. package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +147 -10
  72. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +51 -1
  73. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +29 -7
  74. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +22 -1
  75. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +30 -10
  76. package/common/cpp/react/renderer/components/rnscreens/utils/RectUtil.h +36 -0
  77. package/cpp/RNSScreenRemovalListener.cpp +25 -0
  78. package/cpp/RNSScreenRemovalListener.h +20 -0
  79. package/cpp/RNScreensTurboModule.cpp +31 -23
  80. package/cpp/RNScreensTurboModule.h +17 -20
  81. package/ios/RNSConvert.h +7 -0
  82. package/ios/RNSConvert.mm +24 -0
  83. package/ios/RNSModalScreen.mm +22 -0
  84. package/ios/RNSModule.mm +2 -3
  85. package/ios/RNSScreen.h +2 -1
  86. package/ios/RNSScreen.mm +35 -19
  87. package/ios/RNSScreenContainer.mm +1 -1
  88. package/ios/RNSScreenStack.mm +59 -54
  89. package/ios/RNSScreenStackAnimator.mm +43 -6
  90. package/ios/RNSScreenStackHeaderConfig.h +2 -0
  91. package/ios/RNSScreenStackHeaderConfig.mm +93 -28
  92. package/ios/RNSScreenStackHeaderSubview.mm +8 -0
  93. package/ios/RNSSearchBar.h +5 -5
  94. package/ios/RNSSearchBar.mm +11 -11
  95. package/ios/utils/RCTSurfaceTouchHandler+RNSUtility.h +15 -0
  96. package/ios/utils/RCTSurfaceTouchHandler+RNSUtility.mm +14 -0
  97. package/ios/utils/RCTTouchHandler+RNSUtility.h +15 -0
  98. package/ios/utils/RCTTouchHandler+RNSUtility.mm +15 -0
  99. package/ios/utils/UIView+RNSUtility.h +23 -0
  100. package/ios/utils/UIView+RNSUtility.mm +55 -0
  101. package/lib/commonjs/components/Screen.js +119 -127
  102. package/lib/commonjs/components/Screen.js.map +1 -1
  103. package/lib/commonjs/components/ScreenStack.js +8 -1
  104. package/lib/commonjs/components/ScreenStack.js.map +1 -1
  105. package/lib/commonjs/components/SearchBar.js +39 -36
  106. package/lib/commonjs/components/SearchBar.js.map +1 -1
  107. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  108. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  109. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  110. package/lib/commonjs/native-stack/views/HeaderConfig.js +2 -0
  111. package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -1
  112. package/lib/commonjs/native-stack/views/NativeStackView.js +4 -0
  113. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  114. package/lib/module/components/Screen.js +118 -126
  115. package/lib/module/components/Screen.js.map +1 -1
  116. package/lib/module/components/ScreenStack.js +8 -1
  117. package/lib/module/components/ScreenStack.js.map +1 -1
  118. package/lib/module/components/SearchBar.js +39 -36
  119. package/lib/module/components/SearchBar.js.map +1 -1
  120. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  121. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  122. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  123. package/lib/module/native-stack/views/HeaderConfig.js +2 -0
  124. package/lib/module/native-stack/views/HeaderConfig.js.map +1 -1
  125. package/lib/module/native-stack/views/NativeStackView.js +4 -0
  126. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  127. package/lib/typescript/TransitionProgressContext.d.ts +1 -1
  128. package/lib/typescript/TransitionProgressContext.d.ts.map +1 -1
  129. package/lib/typescript/components/Screen.d.ts +3 -14
  130. package/lib/typescript/components/Screen.d.ts.map +1 -1
  131. package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
  132. package/lib/typescript/components/SearchBar.d.ts +14 -21
  133. package/lib/typescript/components/SearchBar.d.ts.map +1 -1
  134. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +12 -10
  135. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  136. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +12 -10
  137. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  138. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +5 -3
  139. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
  140. package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts +1 -1
  141. package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts.map +1 -1
  142. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts +1 -1
  143. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts.map +1 -1
  144. package/lib/typescript/fabric/SearchBarNativeComponent.d.ts +9 -9
  145. package/lib/typescript/fabric/SearchBarNativeComponent.d.ts.map +1 -1
  146. package/lib/typescript/gesture-handler/RNScreensTurboModule.d.ts +1 -1
  147. package/lib/typescript/gesture-handler/RNScreensTurboModule.d.ts.map +1 -1
  148. package/lib/typescript/native-stack/types.d.ts +39 -14
  149. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  150. package/lib/typescript/native-stack/utils/SafeAreaProviderCompat.d.ts +1 -1
  151. package/lib/typescript/native-stack/utils/SafeAreaProviderCompat.d.ts.map +1 -1
  152. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts +1 -1
  153. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts.map +1 -1
  154. package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts +1 -1
  155. package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts.map +1 -1
  156. package/lib/typescript/native-stack/views/HeaderConfig.d.ts +2 -2
  157. package/lib/typescript/native-stack/views/HeaderConfig.d.ts.map +1 -1
  158. package/lib/typescript/native-stack/views/NativeStackView.d.ts +1 -1
  159. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  160. package/lib/typescript/reanimated/ReanimatedTransitionProgressContext.d.ts +1 -1
  161. package/lib/typescript/reanimated/ReanimatedTransitionProgressContext.d.ts.map +1 -1
  162. package/lib/typescript/types.d.ts +39 -13
  163. package/lib/typescript/types.d.ts.map +1 -1
  164. package/lib/typescript/useTransitionProgress.d.ts +3 -3
  165. package/native-stack/README.md +116 -98
  166. package/package.json +16 -7
  167. package/react-native.config.js +17 -15
  168. package/src/TransitionProgressContext.tsx +1 -1
  169. package/src/components/Screen.tsx +31 -37
  170. package/src/components/ScreenStack.tsx +11 -1
  171. package/src/components/ScreenStackHeaderConfig.tsx +5 -5
  172. package/src/components/ScreenStackHeaderConfig.web.tsx +6 -6
  173. package/src/components/SearchBar.tsx +77 -65
  174. package/src/core.ts +1 -1
  175. package/src/fabric/ModalScreenNativeComponent.ts +2 -0
  176. package/src/fabric/ScreenNativeComponent.ts +2 -0
  177. package/src/fabric/ScreenNavigationContainerNativeComponent.ts +1 -1
  178. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +4 -1
  179. package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +1 -1
  180. package/src/fabric/SearchBarNativeComponent.ts +7 -7
  181. package/src/gesture-handler/ScreenGestureDetector.tsx +5 -5
  182. package/src/gesture-handler/constraints.ts +5 -5
  183. package/src/gesture-handler/fabricUtils.ts +1 -1
  184. package/src/native-stack/contexts/GHContext.tsx +1 -1
  185. package/src/native-stack/navigators/createNativeStackNavigator.tsx +3 -3
  186. package/src/native-stack/types.tsx +29 -4
  187. package/src/native-stack/utils/getDefaultHeaderHeight.tsx +1 -1
  188. package/src/native-stack/utils/getStatusBarHeight.tsx +1 -1
  189. package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +1 -1
  190. package/src/native-stack/utils/useBackPressSubscription.tsx +1 -1
  191. package/src/native-stack/utils/useHeaderHeight.tsx +1 -1
  192. package/src/native-stack/views/FontProcessor.tsx +1 -1
  193. package/src/native-stack/views/HeaderConfig.tsx +3 -1
  194. package/src/native-stack/views/NativeStackView.tsx +13 -9
  195. package/src/reanimated/ReanimatedHeaderHeightContext.tsx +1 -1
  196. package/src/reanimated/ReanimatedNativeStackScreen.tsx +5 -5
  197. package/src/reanimated/ReanimatedScreen.tsx +2 -2
  198. package/src/reanimated/ReanimatedScreenProvider.tsx +1 -1
  199. package/src/reanimated/useReanimatedHeaderHeight.tsx +1 -1
  200. package/src/reanimated/useReanimatedTransitionProgress.tsx +1 -1
  201. package/src/types.tsx +31 -5
  202. package/src/useTransitionProgress.tsx +1 -1
  203. package/windows/README.md +4 -1
@@ -12,49 +12,54 @@ std::function<void(int, bool)> RNScreensTurboModule::finishTransition_;
12
12
  std::function<void(int)> RNScreensTurboModule::disableSwipeBackForTopScreen_;
13
13
 
14
14
  RNScreensTurboModule::RNScreensTurboModule(
15
- std::function<std::array<int, 2>(int)> startTransition,
16
- std::function<void(int, double)> updateTransition,
17
- std::function<void(int, bool)> finishTransition,
18
- std::function<void(int)> disableSwipeBackForTopScreen
19
- ) {
15
+ std::function<std::array<int, 2>(int)> startTransition,
16
+ std::function<void(int, double)> updateTransition,
17
+ std::function<void(int, bool)> finishTransition,
18
+ std::function<void(int)> disableSwipeBackForTopScreen) {
20
19
  startTransition_ = startTransition;
21
20
  updateTransition_ = updateTransition;
22
21
  finishTransition_ = finishTransition;
23
22
  disableSwipeBackForTopScreen_ = disableSwipeBackForTopScreen;
24
23
  }
25
24
 
26
- RNScreensTurboModule::~RNScreensTurboModule() {};
25
+ RNScreensTurboModule::~RNScreensTurboModule(){};
27
26
 
28
- jsi::Value RNScreensTurboModule::get(jsi::Runtime& rt, const jsi::PropNameID& name) {
27
+ jsi::Value RNScreensTurboModule::get(
28
+ jsi::Runtime &rt,
29
+ const jsi::PropNameID &name) {
29
30
  if (name.utf8(rt) == "startTransition") {
30
31
  return jsi::Function::createFromHostFunction(rt, name, 1, startTransition);
31
- }
32
- else if (name.utf8(rt) == "updateTransition") {
32
+ } else if (name.utf8(rt) == "updateTransition") {
33
33
  return jsi::Function::createFromHostFunction(rt, name, 2, updateTransition);
34
- }
35
- else if (name.utf8(rt) == "finishTransition") {
34
+ } else if (name.utf8(rt) == "finishTransition") {
36
35
  return jsi::Function::createFromHostFunction(rt, name, 2, finishTransition);
37
- }
38
- else if (name.utf8(rt) == "disableSwipeBackForTopScreen") {
39
- return jsi::Function::createFromHostFunction(rt, name, 1, disableSwipeBackForTopScreen);
36
+ } else if (name.utf8(rt) == "disableSwipeBackForTopScreen") {
37
+ return jsi::Function::createFromHostFunction(
38
+ rt, name, 1, disableSwipeBackForTopScreen);
40
39
  }
41
40
  return jsi::Value::undefined();
42
41
  }
43
42
 
44
- void RNScreensTurboModule::set(jsi::Runtime&, const jsi::PropNameID&, const jsi::Value&) {};
43
+ void RNScreensTurboModule::set(
44
+ jsi::Runtime &,
45
+ const jsi::PropNameID &,
46
+ const jsi::Value &){};
45
47
 
46
- std::vector<jsi::PropNameID> RNScreensTurboModule::getPropertyNames(jsi::Runtime& rt) {
48
+ std::vector<jsi::PropNameID> RNScreensTurboModule::getPropertyNames(
49
+ jsi::Runtime &rt) {
47
50
  std::vector<jsi::PropNameID> properties;
48
51
  properties.push_back(jsi::PropNameID::forUtf8(rt, "startTransition"));
49
52
  properties.push_back(jsi::PropNameID::forUtf8(rt, "updateTransition"));
50
53
  properties.push_back(jsi::PropNameID::forUtf8(rt, "finishTransition"));
51
- properties.push_back(jsi::PropNameID::forUtf8(rt, "disableSwipeBackForTopScreen"));
54
+ properties.push_back(
55
+ jsi::PropNameID::forUtf8(rt, "disableSwipeBackForTopScreen"));
52
56
  return properties;
53
57
  }
54
58
 
55
59
  JSI_HOST_FUNCTION(RNScreensTurboModule::startTransition) {
56
60
  if (count < 1) {
57
- throw jsi::JSError(rt, "[RNScreens] `startTransition` method requires 1 argument.");
61
+ throw jsi::JSError(
62
+ rt, "[RNScreens] `startTransition` method requires 1 argument.");
58
63
  }
59
64
  int stackTag = arguments[0].asNumber();
60
65
  auto screenTags = startTransition_(stackTag);
@@ -77,7 +82,8 @@ JSI_HOST_FUNCTION(RNScreensTurboModule::startTransition) {
77
82
 
78
83
  JSI_HOST_FUNCTION(RNScreensTurboModule::updateTransition) {
79
84
  if (count < 2) {
80
- throw jsi::JSError(rt, "[RNScreens] `updateTransition` requires 2 arguments.");
85
+ throw jsi::JSError(
86
+ rt, "[RNScreens] `updateTransition` requires 2 arguments.");
81
87
  }
82
88
  int stackTag = arguments[0].asNumber();
83
89
  double progress = arguments[1].asNumber();
@@ -87,7 +93,8 @@ JSI_HOST_FUNCTION(RNScreensTurboModule::updateTransition) {
87
93
 
88
94
  JSI_HOST_FUNCTION(RNScreensTurboModule::finishTransition) {
89
95
  if (count < 2) {
90
- throw jsi::JSError(rt, "[RNScreens] `finishTransition` requires 2 arguments.");
96
+ throw jsi::JSError(
97
+ rt, "[RNScreens] `finishTransition` requires 2 arguments.");
91
98
  }
92
99
  int stackTag = arguments[0].asNumber();
93
100
  bool canceled = arguments[1].getBool();
@@ -96,12 +103,13 @@ JSI_HOST_FUNCTION(RNScreensTurboModule::finishTransition) {
96
103
  }
97
104
 
98
105
  JSI_HOST_FUNCTION(RNScreensTurboModule::disableSwipeBackForTopScreen) {
99
- if (count < 1) {
100
- throw jsi::JSError(rt, "[RNScreens] `startTransition` method requires 1 argument.");
106
+ if (count < 1) {
107
+ throw jsi::JSError(
108
+ rt, "[RNScreens] `startTransition` method requires 1 argument.");
101
109
  }
102
110
  int stackTag = arguments[0].asNumber();
103
111
  disableSwipeBackForTopScreen_(stackTag);
104
112
  return jsi::Value::undefined();
105
113
  }
106
114
 
107
- }
115
+ } // namespace RNScreens
@@ -1,43 +1,40 @@
1
- #include <array>
2
1
  #include <jsi/jsi.h>
2
+ #include <array>
3
3
 
4
- #define JSI_HOST_FUNCTION(NAME) \
5
- jsi::Value NAME( \
6
- jsi::Runtime &rt, \
7
- const jsi::Value &thisValue, \
8
- const jsi::Value *arguments, \
9
- size_t count \
10
- )
4
+ #define JSI_HOST_FUNCTION(NAME) \
5
+ jsi::Value NAME( \
6
+ jsi::Runtime &rt, \
7
+ const jsi::Value &thisValue, \
8
+ const jsi::Value *arguments, \
9
+ size_t count)
11
10
 
12
11
  using namespace facebook;
13
12
 
14
13
  namespace RNScreens {
15
14
 
16
15
  class RNScreensTurboModule : public jsi::HostObject {
17
-
18
16
  static std::function<std::array<int, 2>(int)> startTransition_;
19
17
  static std::function<void(int, double)> updateTransition_;
20
18
  static std::function<void(int, bool)> finishTransition_;
21
19
  static std::function<void(int)> disableSwipeBackForTopScreen_;
22
20
 
23
- public:
21
+ public:
24
22
  static const char MODULE_NAME[];
25
23
 
26
24
  RNScreensTurboModule(
27
- std::function<std::array<int, 2>(int)> startTransition,
28
- std::function<void(int, double)> updateTransition,
29
- std::function<void(int, bool)> finishTransition,
30
- std::function<void(int)> disableSwipeBackForTopScreen
31
- );
25
+ std::function<std::array<int, 2>(int)> startTransition,
26
+ std::function<void(int, double)> updateTransition,
27
+ std::function<void(int, bool)> finishTransition,
28
+ std::function<void(int)> disableSwipeBackForTopScreen);
32
29
  ~RNScreensTurboModule() override;
33
- jsi::Value get(jsi::Runtime& rt, const jsi::PropNameID& name) override;
34
- void set(jsi::Runtime&, const jsi::PropNameID&, const jsi::Value&) override;
35
- std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& rt) override;
30
+ jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &name) override;
31
+ void set(jsi::Runtime &, const jsi::PropNameID &, const jsi::Value &)
32
+ override;
33
+ std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
36
34
  static JSI_HOST_FUNCTION(startTransition);
37
35
  static JSI_HOST_FUNCTION(updateTransition);
38
36
  static JSI_HOST_FUNCTION(finishTransition);
39
37
  static JSI_HOST_FUNCTION(disableSwipeBackForTopScreen);
40
-
41
38
  };
42
39
 
43
- }
40
+ } // namespace RNScreens
package/ios/RNSConvert.h CHANGED
@@ -1,4 +1,5 @@
1
1
  #ifdef RCT_NEW_ARCH_ENABLED
2
+ #import <UIKit/UIKit.h>
2
3
  #import <react/renderer/components/rnscreens/Props.h>
3
4
  #import "RNSEnums.h"
4
5
 
@@ -6,6 +7,12 @@ namespace react = facebook::react;
6
7
 
7
8
  @interface RNSConvert : NSObject
8
9
 
10
+ + (UISemanticContentAttribute)UISemanticContentAttributeFromCppEquivalent:
11
+ (react::RNSScreenStackHeaderConfigDirection)direction;
12
+
13
+ + (UINavigationItemBackButtonDisplayMode)UINavigationItemBackButtonDisplayModeFromCppEquivalent:
14
+ (react::RNSScreenStackHeaderConfigBackButtonDisplayMode)backButtonDisplayMode;
15
+
9
16
  + (RNSScreenStackPresentation)RNSScreenStackPresentationFromCppEquivalent:
10
17
  (react::RNSScreenStackPresentation)stackPresentation;
11
18
 
package/ios/RNSConvert.mm CHANGED
@@ -3,6 +3,30 @@
3
3
  #ifdef RCT_NEW_ARCH_ENABLED
4
4
  @implementation RNSConvert
5
5
 
6
+ + (UISemanticContentAttribute)UISemanticContentAttributeFromCppEquivalent:
7
+ (react::RNSScreenStackHeaderConfigDirection)direction
8
+ {
9
+ switch (direction) {
10
+ case react::RNSScreenStackHeaderConfigDirection::Rtl:
11
+ return UISemanticContentAttributeForceRightToLeft;
12
+ case react::RNSScreenStackHeaderConfigDirection::Ltr:
13
+ return UISemanticContentAttributeForceLeftToRight;
14
+ }
15
+ }
16
+
17
+ + (UINavigationItemBackButtonDisplayMode)UINavigationItemBackButtonDisplayModeFromCppEquivalent:
18
+ (react::RNSScreenStackHeaderConfigBackButtonDisplayMode)backButtonDisplayMode
19
+ {
20
+ switch (backButtonDisplayMode) {
21
+ case react::RNSScreenStackHeaderConfigBackButtonDisplayMode::Default:
22
+ return UINavigationItemBackButtonDisplayModeDefault;
23
+ case react::RNSScreenStackHeaderConfigBackButtonDisplayMode::Generic:
24
+ return UINavigationItemBackButtonDisplayModeGeneric;
25
+ case react::RNSScreenStackHeaderConfigBackButtonDisplayMode::Minimal:
26
+ return UINavigationItemBackButtonDisplayModeMinimal;
27
+ }
28
+ }
29
+
6
30
  + (RNSScreenStackPresentation)RNSScreenStackPresentationFromCppEquivalent:
7
31
  (react::RNSScreenStackPresentation)stackPresentation
8
32
  {
@@ -7,6 +7,28 @@
7
7
 
8
8
  @implementation RNSModalScreen
9
9
 
10
+ // When using UIModalPresentationStyleFullScreen the whole view hierarchy mounted under primary `UITransitionView` is
11
+ // removed, including React's root view, which observes for trait collection changes & sends it to `Appearance` module
12
+ // via system notification centre. To workaround this detached-root-view-situation we emit the event to React's
13
+ // `Appearance` module ourselves. For the RCTRootView observer, visit
14
+ // https://github.com/facebook/react-native/blob/d3e0430deac573fd44792e6005d5de20e9ad2797/packages/react-native/React/Base/RCTRootView.m#L362
15
+ // For more information, see https://github.com/software-mansion/react-native-screens/pull/2211.
16
+ - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
17
+ {
18
+ [super traitCollectionDidChange:previousTraitCollection];
19
+ if (RCTSharedApplication().applicationState == UIApplicationStateBackground ||
20
+ self.stackPresentation != RNSScreenStackPresentationFullScreenModal) {
21
+ return;
22
+ }
23
+
24
+ [[NSNotificationCenter defaultCenter]
25
+ postNotificationName:RCTUserInterfaceStyleDidChangeNotification
26
+ object:self
27
+ userInfo:@{
28
+ RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey : self.traitCollection,
29
+ }];
30
+ }
31
+
10
32
  #ifdef RCT_NEW_ARCH_ENABLED
11
33
  + (react::ComponentDescriptorProvider)componentDescriptorProvider
12
34
  {
package/ios/RNSModule.mm CHANGED
@@ -116,7 +116,7 @@ RCT_EXPORT_MODULE()
116
116
  {
117
117
  RNSScreenStackView *view = [self getScreenStackView:stackTag];
118
118
  if (view != nil && ![view isKindOfClass:[RNSScreenStackView class]]) {
119
- RCTLogError(@"Invalid view type, expecting RNSScreenStackView, got: %@", view);
119
+ RCTLogError(@"[RNScreens] Invalid view type, expecting RNSScreenStackView, got: %@", view);
120
120
  return nil;
121
121
  }
122
122
  return view;
@@ -138,8 +138,7 @@ RCT_EXPORT_MODULE()
138
138
  because depending on the selected architecture, only one method will be called.
139
139
  For `Paper`, it will be constantsToExport, and for `Fabric`, it will be getTurboModule.
140
140
  */
141
- RCTBridge *bridge = [RCTBridge currentBridge];
142
- RCTCxxBridge *cxxBridge = (RCTCxxBridge *)bridge;
141
+ RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
143
142
  if (cxxBridge != nil) {
144
143
  auto jsiRuntime = (jsi::Runtime *)cxxBridge.runtime;
145
144
  if (jsiRuntime != nil) {
package/ios/RNSScreen.h CHANGED
@@ -40,7 +40,7 @@ namespace react = facebook::react;
40
40
  - (void)notifyFinishTransitioning;
41
41
  - (RNSScreenView *)screenView;
42
42
  #ifdef RCT_NEW_ARCH_ENABLED
43
- - (void)setViewToSnapshot:(UIView *)snapshot;
43
+ - (void)setViewToSnapshot;
44
44
  - (CGFloat)calculateHeaderHeightIsModal:(BOOL)isModal;
45
45
  #endif
46
46
 
@@ -56,6 +56,7 @@ namespace react = facebook::react;
56
56
  #endif
57
57
 
58
58
  @property (nonatomic) BOOL fullScreenSwipeEnabled;
59
+ @property (nonatomic) BOOL fullScreenSwipeShadowEnabled;
59
60
  @property (nonatomic) BOOL gestureEnabled;
60
61
  @property (nonatomic) BOOL hasStatusBarHiddenSet;
61
62
  @property (nonatomic) BOOL hasStatusBarStyleSet;
package/ios/RNSScreen.mm CHANGED
@@ -25,6 +25,8 @@
25
25
  #import "RNSScreenStack.h"
26
26
  #import "RNSScreenStackHeaderConfig.h"
27
27
 
28
+ #import "UIView+RNSUtility.h"
29
+
28
30
  #ifdef RCT_NEW_ARCH_ENABLED
29
31
  namespace react = facebook::react;
30
32
  #endif // RCT_NEW_ARCH_ENABLED
@@ -414,7 +416,7 @@ namespace react = facebook::react;
414
416
  [[RNSHeaderHeightChangeEvent alloc] initWithEventName:@"onHeaderHeightChange"
415
417
  reactTag:[NSNumber numberWithInt:self.tag]
416
418
  headerHeight:headerHeight];
417
- [[RCTBridge currentBridge].eventDispatcher notifyObserversOfEvent:event];
419
+ [self postNotificationForEventDispatcherObserversWithEvent:event];
418
420
  #else
419
421
  if (self.onHeaderHeightChange) {
420
422
  self.onHeaderHeightChange(@{
@@ -473,22 +475,13 @@ namespace react = facebook::react;
473
475
  }
474
476
  }
475
477
 
476
- #ifdef RCT_NEW_ARCH_ENABLED
477
- - (RCTSurfaceTouchHandler *)touchHandler
478
- #else
479
- - (RCTTouchHandler *)touchHandler
480
- #endif
478
+ - (nullable RNS_TOUCH_HANDLER_ARCH_TYPE *)touchHandler
481
479
  {
482
480
  if (_touchHandler != nil) {
483
481
  return _touchHandler;
484
482
  }
485
- UIView *parent = [self superview];
486
- while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)])
487
- parent = parent.superview;
488
- if (parent != nil) {
489
- return [parent performSelector:@selector(touchHandler)];
490
- }
491
- return nil;
483
+
484
+ return [self rnscreens_findTouchHandlerInAncestorChain];
492
485
  }
493
486
 
494
487
  - (void)notifyFinishTransitioning
@@ -509,7 +502,7 @@ namespace react = facebook::react;
509
502
  progress:progress
510
503
  closing:closing
511
504
  goingForward:goingForward];
512
- [[RCTBridge currentBridge].eventDispatcher notifyObserversOfEvent:event];
505
+ [self postNotificationForEventDispatcherObserversWithEvent:event];
513
506
  #else
514
507
  if (self.onTransitionProgress) {
515
508
  self.onTransitionProgress(@{
@@ -521,6 +514,14 @@ namespace react = facebook::react;
521
514
  #endif
522
515
  }
523
516
 
517
+ #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
518
+ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
519
+ - (void)presentationControllerDidAttemptToDismiss:(UIPresentationController *)presentationController
520
+ {
521
+ [self notifyGestureCancel];
522
+ }
523
+ #endif
524
+
524
525
  - (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController
525
526
  {
526
527
  // We need to call both "cancel" and "reset" here because RN's gesture recognizer
@@ -659,6 +660,14 @@ namespace react = facebook::react;
659
660
  #pragma mark - Fabric specific
660
661
  #ifdef RCT_NEW_ARCH_ENABLED
661
662
 
663
+ - (void)postNotificationForEventDispatcherObserversWithEvent:(NSObject<RCTEvent> *)event
664
+ {
665
+ NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:event, @"event", nil];
666
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED"
667
+ object:nil
668
+ userInfo:userInfo];
669
+ }
670
+
662
671
  - (BOOL)hasHeaderConfig
663
672
  {
664
673
  return _config != nil;
@@ -702,6 +711,8 @@ namespace react = facebook::react;
702
711
 
703
712
  [self setFullScreenSwipeEnabled:newScreenProps.fullScreenSwipeEnabled];
704
713
 
714
+ [self setFullScreenSwipeShadowEnabled:newScreenProps.fullScreenSwipeShadowEnabled];
715
+
705
716
  [self setGestureEnabled:newScreenProps.gestureEnabled];
706
717
 
707
718
  [self setTransitionDuration:[NSNumber numberWithInt:newScreenProps.transitionDuration]];
@@ -785,7 +796,7 @@ namespace react = facebook::react;
785
796
  _newLayoutMetrics = layoutMetrics;
786
797
  _oldLayoutMetrics = oldLayoutMetrics;
787
798
  UIViewController *parentVC = self.reactViewController.parentViewController;
788
- if (parentVC != nil && ![parentVC isKindOfClass:[RNSNavigationController class]]) {
799
+ if (parentVC == nil || ![parentVC isKindOfClass:[RNSNavigationController class]]) {
789
800
  [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
790
801
  }
791
802
  // when screen is mounted under RNSNavigationController it's size is controller
@@ -1380,12 +1391,16 @@ Class<RCTComponentViewProtocol> RNSScreenCls(void)
1380
1391
  #ifdef RCT_NEW_ARCH_ENABLED
1381
1392
  #pragma mark - Fabric specific
1382
1393
 
1383
- - (void)setViewToSnapshot:(UIView *)snapshot
1394
+ - (void)setViewToSnapshot
1384
1395
  {
1385
1396
  UIView *superView = self.view.superview;
1386
- [self.view removeFromSuperview];
1387
- self.view = snapshot;
1388
- [superView addSubview:self.view];
1397
+ // if we dismissed the view natively, it will already be detached from view hierarchy
1398
+ if (self.view.window != nil) {
1399
+ UIView *snapshot = [self.view snapshotViewAfterScreenUpdates:NO];
1400
+ [self.view removeFromSuperview];
1401
+ self.view = snapshot;
1402
+ [superView addSubview:snapshot];
1403
+ }
1389
1404
  }
1390
1405
 
1391
1406
  #else
@@ -1426,6 +1441,7 @@ RCT_EXPORT_MODULE()
1426
1441
  RCT_REMAP_VIEW_PROPERTY(activityState, activityStateOrNil, NSNumber)
1427
1442
  RCT_EXPORT_VIEW_PROPERTY(customAnimationOnSwipe, BOOL);
1428
1443
  RCT_EXPORT_VIEW_PROPERTY(fullScreenSwipeEnabled, BOOL);
1444
+ RCT_EXPORT_VIEW_PROPERTY(fullScreenSwipeShadowEnabled, BOOL);
1429
1445
  RCT_EXPORT_VIEW_PROPERTY(gestureEnabled, BOOL)
1430
1446
  RCT_EXPORT_VIEW_PROPERTY(gestureResponseDistance, NSDictionary)
1431
1447
  RCT_EXPORT_VIEW_PROPERTY(hideKeyboardOnSwipe, BOOL)
@@ -60,7 +60,7 @@ namespace react = facebook::react;
60
60
 
61
61
  - (instancetype)init
62
62
  {
63
- if (self = [super init]) {
63
+ if (self = [super initWithFrame:CGRectZero]) {
64
64
  #ifdef RCT_NEW_ARCH_ENABLED
65
65
  static const auto defaultProps = std::make_shared<const react::RNSScreenContainerProps>();
66
66
  _props = defaultProps;
@@ -1,12 +1,15 @@
1
1
  #ifdef RCT_NEW_ARCH_ENABLED
2
2
  #import <React/RCTFabricComponentsPlugins.h>
3
+ #import <React/RCTFabricSurface.h>
3
4
  #import <React/RCTMountingTransactionObserving.h>
4
5
  #import <React/RCTSurfaceTouchHandler.h>
6
+ #import <React/RCTSurfaceView.h>
5
7
  #import <React/UIView+React.h>
6
8
  #import <react/renderer/components/rnscreens/ComponentDescriptors.h>
7
9
  #import <react/renderer/components/rnscreens/EventEmitters.h>
8
10
  #import <react/renderer/components/rnscreens/Props.h>
9
11
  #import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
12
+ #import "RCTSurfaceTouchHandler+RNSUtility.h"
10
13
  #else
11
14
  #import <React/RCTBridge.h>
12
15
  #import <React/RCTRootContentView.h>
@@ -14,6 +17,7 @@
14
17
  #import <React/RCTTouchHandler.h>
15
18
  #import <React/RCTUIManager.h>
16
19
  #import <React/RCTUIManagerUtils.h>
20
+ #import "RCTTouchHandler+RNSUtility.h"
17
21
  #endif // RCT_NEW_ARCH_ENABLED
18
22
 
19
23
  #import "RNSScreen.h"
@@ -22,6 +26,8 @@
22
26
  #import "RNSScreenStackHeaderConfig.h"
23
27
  #import "RNSScreenWindowTraits.h"
24
28
 
29
+ #import "UIView+RNSUtility.h"
30
+
25
31
  #ifdef RCT_NEW_ARCH_ENABLED
26
32
  namespace react = facebook::react;
27
33
  #endif // RCT_NEW_ARCH_ENABLED
@@ -112,12 +118,8 @@ namespace react = facebook::react;
112
118
  BOOL _invalidated;
113
119
  BOOL _isFullWidthSwiping;
114
120
  UIPercentDrivenInteractiveTransition *_interactionController;
115
- BOOL _hasLayout;
116
121
  __weak RNSScreenStackManager *_manager;
117
122
  BOOL _updateScheduled;
118
- #ifdef RCT_NEW_ARCH_ENABLED
119
- UIView *_snapshot;
120
- #endif
121
123
  }
122
124
 
123
125
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -136,7 +138,6 @@ namespace react = facebook::react;
136
138
  - (instancetype)initWithManager:(RNSScreenStackManager *)manager
137
139
  {
138
140
  if (self = [super init]) {
139
- _hasLayout = NO;
140
141
  _invalidated = NO;
141
142
  _manager = manager;
142
143
  [self initCommonProps];
@@ -266,18 +267,9 @@ namespace react = facebook::react;
266
267
  - (void)maybeAddToParentAndUpdateContainer
267
268
  {
268
269
  BOOL wasScreenMounted = _controller.parentViewController != nil;
269
- #ifdef RCT_NEW_ARCH_ENABLED
270
- BOOL isScreenReadyForShowing = self.window;
271
- #else
272
- BOOL isScreenReadyForShowing = self.window && _hasLayout;
273
- #endif
274
- if (!isScreenReadyForShowing && !wasScreenMounted) {
275
- // We wait with adding to parent controller until the stack is mounted and has its initial
276
- // layout done.
277
- // If we add it before layout, some of the items (specifically items from the navigation bar),
278
- // won't be able to position properly. Also the position and size of such items, even if it
279
- // happens to change, won't be properly updated (this is perhaps some internal issue of UIKit).
280
- // If we add it when window is not attached, some of the view transitions will be bloced (i.e.
270
+ if (!self.window && !wasScreenMounted) {
271
+ // We wait with adding to parent controller until the stack is mounted.
272
+ // If we add it when window is not attached, some of the view transitions will be blocked (i.e.
281
273
  // modal transitions) and the internal view controler's state will get out of sync with what's
282
274
  // on screen without us knowing.
283
275
  return;
@@ -382,9 +374,12 @@ namespace react = facebook::react;
382
374
  [newControllers removeObjectsInArray:_presentedModals];
383
375
 
384
376
  // We need to find bottom-most view controller that should stay on the stack
385
- // for the duration of transition. There are couple of scenarios:
386
- // (1) No modals are presented or all modals were presented by this RNSNavigationController,
387
- // (2) There are modals presented by other RNSNavigationControllers (nested/outer)
377
+ // for the duration of transition.
378
+
379
+ // There are couple of scenarios:
380
+ // (1) no modals are presented or all modals were presented by this RNSNavigationController,
381
+ // (2) there are modals presented by other RNSNavigationControllers (nested/outer),
382
+ // (3) there are modals presented by other controllers (e.g. React Native's Modal view).
388
383
 
389
384
  // Last controller that is common for both _presentedModals & controllers
390
385
  __block UIViewController *changeRootController = _controller;
@@ -479,16 +474,35 @@ namespace react = facebook::react;
479
474
  }
480
475
  };
481
476
 
477
+ // changeRootController is the last controller that *is owned by this stack*, and should stay unchanged after this
478
+ // batch of transitions. Therefore changeRootController.presentedViewController is the first constroller to be
479
+ // dismissed (implying also all controllers above). Notice here, that firstModalToBeDismissed could have been
480
+ // RNSScreen modal presented from *this* stack, another stack, or any other view controller with modal presentation
481
+ // provided by third-party libraries (e.g. React Native's Modal view). In case of presence of other (not managed by
482
+ // us) modal controllers, weird interactions might arise. The code below, besides handling our presentation /
483
+ // dismissal logic also attempts to handle possible wide gamut of cases of interactions with third-party modal
484
+ // controllers, however it's not perfect.
485
+ // TODO: Find general way to manage owned and foreign modal view controllers and refactor this code. Consider building
486
+ // model first (data structue, attempting to be aware of all modals in presentation and some text-like algorithm for
487
+ // computing required operations).
488
+
482
489
  UIViewController *firstModalToBeDismissed = changeRootController.presentedViewController;
490
+
483
491
  if (firstModalToBeDismissed != nil) {
484
492
  BOOL shouldAnimate = changeRootIndex == controllers.count &&
485
493
  [firstModalToBeDismissed isKindOfClass:[RNSScreen class]] &&
486
494
  ((RNSScreen *)firstModalToBeDismissed).screenView.stackAnimation != RNSScreenStackAnimationNone;
487
495
 
488
- if ([_presentedModals containsObject:firstModalToBeDismissed]) {
496
+ if ([_presentedModals containsObject:firstModalToBeDismissed] ||
497
+ ![firstModalToBeDismissed isKindOfClass:RNSScreen.class]) {
489
498
  // We dismiss every VC that was presented by changeRootController VC or its descendant.
490
499
  // After the series of dismissals is completed we run completion block in which
491
500
  // we present modals on top of changeRootController (which may be the this stack VC)
501
+ //
502
+ // There also might the second case, where the firstModalToBeDismissed is foreign.
503
+ // See: https://github.com/software-mansion/react-native-screens/issues/2048
504
+ // For now, to mitigate the issue, we also decide to trigger its dismissal before
505
+ // starting the presentation chain down below in finish() callback.
492
506
  [changeRootController dismissViewControllerAnimated:shouldAnimate completion:finish];
493
507
  return;
494
508
  }
@@ -709,19 +723,8 @@ namespace react = facebook::react;
709
723
  // item is close to an edge and we start pulling from edge we want the Touchable to be cancelled.
710
724
  // Without the below code the Touchable will remain active (highlighted) for the duration of back
711
725
  // gesture and onPress may fire when we release the finger.
712
- UIView *parent = _controller.view;
713
- while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)])
714
- parent = parent.superview;
715
- if (parent != nil) {
716
- #ifdef RCT_NEW_ARCH_ENABLED
717
- RCTSurfaceTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)];
718
- #else
719
- RCTTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)];
720
- #endif
721
- [touchHandler setEnabled:NO];
722
- [touchHandler setEnabled:YES];
723
- [touchHandler reset];
724
- }
726
+
727
+ [[self rnscreens_findTouchHandlerInAncestorChain] rnscreens_cancelTouches];
725
728
  }
726
729
 
727
730
  - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
@@ -855,6 +858,7 @@ namespace react = facebook::react;
855
858
  [_interactionController cancelInteractiveTransition];
856
859
  }
857
860
  _interactionController = nil;
861
+ _isFullWidthSwiping = NO;
858
862
  }
859
863
  default: {
860
864
  break;
@@ -901,6 +905,10 @@ namespace react = facebook::react;
901
905
  {
902
906
  [self emitOnFinishTransitioningEvent];
903
907
  [RNSScreenWindowTraits updateWindowTraits];
908
+ // Because of the bug that caused view to have incorrect dimensions while changing the orientation,
909
+ // we need to signalize that it needs to be layouted.
910
+ // see https://github.com/software-mansion/react-native-screens/pull/1970
911
+ [_controller.view setNeedsLayout];
904
912
  }
905
913
  #endif
906
914
 
@@ -1055,7 +1063,6 @@ namespace react = facebook::react;
1055
1063
  // set yet, however the layout call is already enqueued on ui thread. Enqueuing update call on the
1056
1064
  // ui queue will guarantee that the update will run after layout.
1057
1065
  dispatch_async(dispatch_get_main_queue(), ^{
1058
- self->_hasLayout = YES;
1059
1066
  [self maybeAddToParentAndUpdateContainer];
1060
1067
  });
1061
1068
  }
@@ -1107,14 +1114,14 @@ namespace react = facebook::react;
1107
1114
 
1108
1115
  [_reactSubviews insertObject:(RNSScreenView *)childComponentView atIndex:index];
1109
1116
  ((RNSScreenView *)childComponentView).reactSuperview = self;
1110
- dispatch_async(dispatch_get_main_queue(), ^{
1111
- [self maybeAddToParentAndUpdateContainer];
1112
- });
1117
+ // Container update is done after all mount operations are executed in
1118
+ // `- [RNSScreenStackView mountingTransactionDidMount: withSurfaceTelemetry:]`
1113
1119
  }
1114
1120
 
1115
1121
  - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
1116
1122
  {
1117
1123
  RNSScreenView *screenChildComponent = (RNSScreenView *)childComponentView;
1124
+
1118
1125
  // We should only do a snapshot of a screen that is on the top.
1119
1126
  // We also check `_presentedModals` since if you push 2 modals, second one is not a "child" of _controller.
1120
1127
  // Also, when dissmised with a gesture, the screen already is not under the window, so we don't need to apply
@@ -1122,7 +1129,7 @@ namespace react = facebook::react;
1122
1129
  if (screenChildComponent.window != nil &&
1123
1130
  ((screenChildComponent == _controller.visibleViewController.view && _presentedModals.count < 2) ||
1124
1131
  screenChildComponent == [_presentedModals.lastObject view])) {
1125
- [screenChildComponent.controller setViewToSnapshot:_snapshot];
1132
+ [screenChildComponent.controller setViewToSnapshot];
1126
1133
  }
1127
1134
 
1128
1135
  RCTAssert(
@@ -1142,24 +1149,22 @@ namespace react = facebook::react;
1142
1149
  screenChildComponent.reactSuperview = nil;
1143
1150
  [_reactSubviews removeObject:screenChildComponent];
1144
1151
  [screenChildComponent removeFromSuperview];
1145
- dispatch_async(dispatch_get_main_queue(), ^{
1146
- [self maybeAddToParentAndUpdateContainer];
1147
- });
1148
1152
  }
1149
1153
 
1150
- - (void)takeSnapshot
1154
+ - (void)mountingTransactionDidMount:(const facebook::react::MountingTransaction &)transaction
1155
+ withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry
1151
1156
  {
1152
- _snapshot = [_controller.visibleViewController.view snapshotViewAfterScreenUpdates:NO];
1153
- }
1154
-
1155
- - (void)mountingTransactionWillMount:(react::MountingTransaction const &)transaction
1156
- withSurfaceTelemetry:(react::SurfaceTelemetry const &)surfaceTelemetry
1157
- {
1158
- for (auto &mutation : transaction.getMutations()) {
1159
- if (mutation.type == react::ShadowViewMutation::Type::Remove && mutation.parentShadowView.componentName != nil &&
1160
- strcmp(mutation.parentShadowView.componentName, "RNSScreenStack") == 0) {
1161
- [self takeSnapshot];
1162
- return;
1157
+ for (const auto &mutation : transaction.getMutations()) {
1158
+ if (mutation.parentShadowView.tag == self.tag &&
1159
+ (mutation.type == react::ShadowViewMutation::Type::Insert ||
1160
+ mutation.type == react::ShadowViewMutation::Type::Remove)) {
1161
+ // we need to wait until children have their layout set. At this point they don't have the layout
1162
+ // set yet, however the layout call is already enqueued on ui thread. Enqueuing update call on the
1163
+ // ui queue will guarantee that the update will run after layout.
1164
+ dispatch_async(dispatch_get_main_queue(), ^{
1165
+ [self maybeAddToParentAndUpdateContainer];
1166
+ });
1167
+ break;
1163
1168
  }
1164
1169
  }
1165
1170
  }