react-native-screens 4.0.0-beta.8 → 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 (271) 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/InsetsObserverProxy.kt +2 -4
  5. package/android/src/main/java/com/swmansion/rnscreens/NativeDismissalObserver.kt +12 -0
  6. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +11 -4
  7. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +24 -6
  8. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +64 -68
  9. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +1 -0
  10. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetBehaviorExt.kt +42 -0
  11. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/DimmingFragment.kt +24 -19
  12. package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetUtils.kt +8 -0
  13. package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +24 -0
  14. package/android/src/main/jni/CMakeLists.txt +28 -19
  15. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +2 -2
  16. package/ios/RNSConvert.h +13 -4
  17. package/ios/RNSConvert.mm +50 -28
  18. package/ios/RNSEnums.h +47 -0
  19. package/ios/RNSPercentDrivenInteractiveTransition.h +12 -0
  20. package/ios/RNSPercentDrivenInteractiveTransition.mm +69 -0
  21. package/ios/RNSScreen.h +14 -0
  22. package/ios/RNSScreen.mm +30 -5
  23. package/ios/RNSScreenStack.mm +74 -9
  24. package/ios/RNSScreenStackAnimator.h +13 -1
  25. package/ios/RNSScreenStackAnimator.mm +233 -130
  26. package/ios/RNSScreenStackHeaderConfig.h +1 -1
  27. package/ios/RNSScreenStackHeaderConfig.mm +39 -29
  28. package/lib/commonjs/components/DebugContainer.js +40 -0
  29. package/lib/commonjs/components/DebugContainer.js.map +1 -0
  30. package/lib/commonjs/components/DebugContainer.web.js +15 -0
  31. package/lib/commonjs/components/DebugContainer.web.js.map +1 -0
  32. package/lib/commonjs/components/FullWindowOverlay.js +8 -5
  33. package/lib/commonjs/components/FullWindowOverlay.js.map +1 -1
  34. package/lib/commonjs/components/Screen.js +35 -10
  35. package/lib/commonjs/components/Screen.js.map +1 -1
  36. package/lib/commonjs/components/ScreenContainer.js +3 -5
  37. package/lib/commonjs/components/ScreenContainer.js.map +1 -1
  38. package/lib/commonjs/components/ScreenContainer.web.js +3 -4
  39. package/lib/commonjs/components/ScreenContainer.web.js.map +1 -1
  40. package/lib/commonjs/components/ScreenContentWrapper.js +2 -4
  41. package/lib/commonjs/components/ScreenContentWrapper.js.map +1 -1
  42. package/lib/commonjs/components/ScreenContentWrapper.web.js +1 -2
  43. package/lib/commonjs/components/ScreenContentWrapper.web.js.map +1 -1
  44. package/lib/commonjs/components/ScreenFooter.js +2 -8
  45. package/lib/commonjs/components/ScreenFooter.js.map +1 -1
  46. package/lib/commonjs/components/ScreenFooter.web.js +1 -2
  47. package/lib/commonjs/components/ScreenFooter.web.js.map +1 -1
  48. package/lib/commonjs/components/ScreenStack.js +47 -9
  49. package/lib/commonjs/components/ScreenStack.js.map +1 -1
  50. package/lib/commonjs/components/ScreenStack.web.js +2 -1
  51. package/lib/commonjs/components/ScreenStack.web.js.map +1 -1
  52. package/lib/commonjs/components/ScreenStackHeaderConfig.js +14 -10
  53. package/lib/commonjs/components/ScreenStackHeaderConfig.js.map +1 -1
  54. package/lib/commonjs/components/ScreenStackItem.js +99 -0
  55. package/lib/commonjs/components/ScreenStackItem.js.map +1 -0
  56. package/lib/commonjs/components/SearchBar.js +5 -5
  57. package/lib/commonjs/components/SearchBar.js.map +1 -1
  58. package/lib/commonjs/components/SearchBar.web.js +3 -4
  59. package/lib/commonjs/components/SearchBar.web.js.map +1 -1
  60. package/lib/commonjs/components/helpers/usePrevious.js +15 -0
  61. package/lib/commonjs/components/helpers/usePrevious.js.map +1 -0
  62. package/lib/commonjs/contexts.js +11 -0
  63. package/lib/commonjs/contexts.js.map +1 -0
  64. package/lib/commonjs/core.js +0 -3
  65. package/lib/commonjs/core.js.map +1 -1
  66. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  67. package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  68. package/lib/commonjs/gesture-handler/GestureDetectorProvider.js +2 -2
  69. package/lib/commonjs/gesture-handler/GestureDetectorProvider.js.map +1 -1
  70. package/lib/commonjs/gesture-handler/ScreenGestureDetector.js +3 -3
  71. package/lib/commonjs/gesture-handler/ScreenGestureDetector.js.map +1 -1
  72. package/lib/commonjs/gesture-handler/fabricUtils.js +54 -18
  73. package/lib/commonjs/gesture-handler/fabricUtils.js.map +1 -1
  74. package/lib/commonjs/index.js +23 -86
  75. package/lib/commonjs/index.js.map +1 -1
  76. package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js +4 -0
  77. package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js.map +1 -1
  78. package/lib/commonjs/native-stack/views/FooterComponent.js +2 -2
  79. package/lib/commonjs/native-stack/views/FooterComponent.js.map +1 -1
  80. package/lib/commonjs/native-stack/views/HeaderConfig.js +10 -8
  81. package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -1
  82. package/lib/commonjs/native-stack/views/NativeStackView.js +34 -39
  83. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  84. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +2 -2
  85. package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -1
  86. package/lib/commonjs/reanimated/ReanimatedScreen.js +2 -2
  87. package/lib/commonjs/reanimated/ReanimatedScreen.js.map +1 -1
  88. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +2 -2
  89. package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -1
  90. package/lib/commonjs/utils.js +28 -6
  91. package/lib/commonjs/utils.js.map +1 -1
  92. package/lib/module/components/DebugContainer.js +31 -0
  93. package/lib/module/components/DebugContainer.js.map +1 -0
  94. package/lib/module/components/DebugContainer.web.js +6 -0
  95. package/lib/module/components/DebugContainer.web.js.map +1 -0
  96. package/lib/module/components/FullWindowOverlay.js +9 -6
  97. package/lib/module/components/FullWindowOverlay.js.map +1 -1
  98. package/lib/module/components/Screen.js +34 -9
  99. package/lib/module/components/Screen.js.map +1 -1
  100. package/lib/module/components/ScreenContainer.js +2 -4
  101. package/lib/module/components/ScreenContainer.js.map +1 -1
  102. package/lib/module/components/ScreenContainer.web.js +2 -3
  103. package/lib/module/components/ScreenContainer.web.js.map +1 -1
  104. package/lib/module/components/ScreenContentWrapper.js +1 -3
  105. package/lib/module/components/ScreenContentWrapper.js.map +1 -1
  106. package/lib/module/components/ScreenContentWrapper.web.js +0 -1
  107. package/lib/module/components/ScreenContentWrapper.web.js.map +1 -1
  108. package/lib/module/components/ScreenFooter.js +1 -7
  109. package/lib/module/components/ScreenFooter.js.map +1 -1
  110. package/lib/module/components/ScreenFooter.web.js +0 -1
  111. package/lib/module/components/ScreenFooter.web.js.map +1 -1
  112. package/lib/module/components/ScreenStack.js +46 -8
  113. package/lib/module/components/ScreenStack.js.map +1 -1
  114. package/lib/module/components/ScreenStack.web.js +2 -1
  115. package/lib/module/components/ScreenStack.web.js.map +1 -1
  116. package/lib/module/components/ScreenStackHeaderConfig.js +14 -8
  117. package/lib/module/components/ScreenStackHeaderConfig.js.map +1 -1
  118. package/lib/module/components/ScreenStackItem.js +90 -0
  119. package/lib/module/components/ScreenStackItem.js.map +1 -0
  120. package/lib/module/components/SearchBar.js +3 -3
  121. package/lib/module/components/SearchBar.js.map +1 -1
  122. package/lib/module/components/SearchBar.web.js +2 -3
  123. package/lib/module/components/SearchBar.web.js.map +1 -1
  124. package/lib/module/components/helpers/usePrevious.js +9 -0
  125. package/lib/module/components/helpers/usePrevious.js.map +1 -0
  126. package/lib/module/contexts.js +4 -0
  127. package/lib/module/contexts.js.map +1 -0
  128. package/lib/module/core.js +0 -3
  129. package/lib/module/core.js.map +1 -1
  130. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  131. package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -1
  132. package/lib/module/gesture-handler/GestureDetectorProvider.js +1 -1
  133. package/lib/module/gesture-handler/GestureDetectorProvider.js.map +1 -1
  134. package/lib/module/gesture-handler/ScreenGestureDetector.js +3 -3
  135. package/lib/module/gesture-handler/ScreenGestureDetector.js.map +1 -1
  136. package/lib/module/gesture-handler/fabricUtils.js +55 -17
  137. package/lib/module/gesture-handler/fabricUtils.js.map +1 -1
  138. package/lib/module/index.js +12 -18
  139. package/lib/module/index.js.map +1 -1
  140. package/lib/module/native-stack/navigators/createNativeStackNavigator.js +4 -0
  141. package/lib/module/native-stack/navigators/createNativeStackNavigator.js.map +1 -1
  142. package/lib/module/native-stack/views/FooterComponent.js +1 -1
  143. package/lib/module/native-stack/views/FooterComponent.js.map +1 -1
  144. package/lib/module/native-stack/views/HeaderConfig.js +3 -1
  145. package/lib/module/native-stack/views/HeaderConfig.js.map +1 -1
  146. package/lib/module/native-stack/views/NativeStackView.js +28 -33
  147. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  148. package/lib/module/reanimated/ReanimatedNativeStackScreen.js +1 -2
  149. package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -1
  150. package/lib/module/reanimated/ReanimatedScreen.js +1 -2
  151. package/lib/module/reanimated/ReanimatedScreen.js.map +1 -1
  152. package/lib/module/reanimated/ReanimatedScreenProvider.js +1 -1
  153. package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -1
  154. package/lib/module/utils.js +26 -5
  155. package/lib/module/utils.js.map +1 -1
  156. package/lib/typescript/components/DebugContainer.d.ts +15 -0
  157. package/lib/typescript/components/DebugContainer.d.ts.map +1 -0
  158. package/lib/typescript/components/DebugContainer.web.d.ts +4 -0
  159. package/lib/typescript/components/DebugContainer.web.d.ts.map +1 -0
  160. package/lib/typescript/components/FullWindowOverlay.d.ts.map +1 -1
  161. package/lib/typescript/components/Screen.d.ts +2 -7
  162. package/lib/typescript/components/Screen.d.ts.map +1 -1
  163. package/lib/typescript/components/Screen.web.d.ts +1 -1
  164. package/lib/typescript/components/Screen.web.d.ts.map +1 -1
  165. package/lib/typescript/components/ScreenContainer.d.ts +1 -3
  166. package/lib/typescript/components/ScreenContainer.d.ts.map +1 -1
  167. package/lib/typescript/components/ScreenContainer.web.d.ts +2 -3
  168. package/lib/typescript/components/ScreenContainer.web.d.ts.map +1 -1
  169. package/lib/typescript/components/ScreenContentWrapper.d.ts +0 -1
  170. package/lib/typescript/components/ScreenContentWrapper.d.ts.map +1 -1
  171. package/lib/typescript/components/ScreenContentWrapper.web.d.ts +0 -1
  172. package/lib/typescript/components/ScreenContentWrapper.web.d.ts.map +1 -1
  173. package/lib/typescript/components/ScreenFooter.d.ts +0 -4
  174. package/lib/typescript/components/ScreenFooter.d.ts.map +1 -1
  175. package/lib/typescript/components/ScreenFooter.web.d.ts +0 -1
  176. package/lib/typescript/components/ScreenFooter.web.d.ts.map +1 -1
  177. package/lib/typescript/components/ScreenStack.d.ts +1 -1
  178. package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
  179. package/lib/typescript/components/ScreenStack.web.d.ts +2 -1
  180. package/lib/typescript/components/ScreenStack.web.d.ts.map +1 -1
  181. package/lib/typescript/components/ScreenStackHeaderConfig.d.ts +3 -3
  182. package/lib/typescript/components/ScreenStackHeaderConfig.d.ts.map +1 -1
  183. package/lib/typescript/components/ScreenStackHeaderConfig.web.d.ts +1 -1
  184. package/lib/typescript/components/ScreenStackHeaderConfig.web.d.ts.map +1 -1
  185. package/lib/typescript/components/ScreenStackItem.d.ts +11 -0
  186. package/lib/typescript/components/ScreenStackItem.d.ts.map +1 -0
  187. package/lib/typescript/components/SearchBar.d.ts +1 -15
  188. package/lib/typescript/components/SearchBar.d.ts.map +1 -1
  189. package/lib/typescript/components/SearchBar.web.d.ts +2 -3
  190. package/lib/typescript/components/SearchBar.web.d.ts.map +1 -1
  191. package/lib/typescript/components/helpers/usePrevious.d.ts +2 -0
  192. package/lib/typescript/components/helpers/usePrevious.d.ts.map +1 -0
  193. package/lib/typescript/contexts.d.ts +5 -0
  194. package/lib/typescript/contexts.d.ts.map +1 -0
  195. package/lib/typescript/core.d.ts +0 -1
  196. package/lib/typescript/core.d.ts.map +1 -1
  197. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +9 -3
  198. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  199. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +2 -2
  200. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  201. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +2 -2
  202. package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts.map +1 -1
  203. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts +1 -1
  204. package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts.map +1 -1
  205. package/lib/typescript/gesture-handler/ScreenGestureDetector.d.ts +2 -2
  206. package/lib/typescript/gesture-handler/ScreenGestureDetector.d.ts.map +1 -1
  207. package/lib/typescript/gesture-handler/fabricUtils.d.ts +7 -5
  208. package/lib/typescript/gesture-handler/fabricUtils.d.ts.map +1 -1
  209. package/lib/typescript/index.d.ts +10 -16
  210. package/lib/typescript/index.d.ts.map +1 -1
  211. package/lib/typescript/native-stack/navigators/createNativeStackNavigator.d.ts +3 -0
  212. package/lib/typescript/native-stack/navigators/createNativeStackNavigator.d.ts.map +1 -1
  213. package/lib/typescript/native-stack/types.d.ts +58 -12
  214. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  215. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts +1 -1
  216. package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts.map +1 -1
  217. package/lib/typescript/native-stack/views/HeaderConfig.d.ts.map +1 -1
  218. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  219. package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +1 -1
  220. package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts.map +1 -1
  221. package/lib/typescript/reanimated/ReanimatedScreen.d.ts +1 -1
  222. package/lib/typescript/reanimated/ReanimatedScreen.d.ts.map +1 -1
  223. package/lib/typescript/reanimated/ReanimatedScreenProvider.d.ts.map +1 -1
  224. package/lib/typescript/types.d.ts +52 -16
  225. package/lib/typescript/types.d.ts.map +1 -1
  226. package/lib/typescript/utils.d.ts +26 -1
  227. package/lib/typescript/utils.d.ts.map +1 -1
  228. package/native-stack/README.md +5 -4
  229. package/native-stack/package.json +4 -4
  230. package/package.json +1 -1
  231. package/react-native.config.js +16 -28
  232. package/src/components/DebugContainer.tsx +47 -0
  233. package/src/components/DebugContainer.web.tsx +7 -0
  234. package/src/components/FullWindowOverlay.tsx +10 -2
  235. package/src/components/Screen.tsx +52 -24
  236. package/src/components/Screen.web.tsx +1 -1
  237. package/src/components/ScreenContainer.tsx +4 -11
  238. package/src/components/ScreenContainer.web.tsx +2 -3
  239. package/src/components/ScreenContentWrapper.tsx +2 -5
  240. package/src/components/ScreenContentWrapper.web.tsx +1 -2
  241. package/src/components/ScreenFooter.tsx +2 -8
  242. package/src/components/ScreenFooter.web.tsx +1 -2
  243. package/src/components/ScreenStack.tsx +99 -12
  244. package/src/components/ScreenStack.web.tsx +3 -1
  245. package/src/components/ScreenStackHeaderConfig.tsx +28 -13
  246. package/src/components/ScreenStackHeaderConfig.web.tsx +1 -1
  247. package/src/components/ScreenStackItem.tsx +162 -0
  248. package/src/components/SearchBar.tsx +4 -7
  249. package/src/components/SearchBar.web.tsx +2 -3
  250. package/src/components/helpers/usePrevious.tsx +11 -0
  251. package/src/contexts.tsx +9 -0
  252. package/src/core.ts +0 -3
  253. package/src/fabric/ModalScreenNativeComponent.ts +11 -3
  254. package/src/fabric/ScreenNativeComponent.ts +2 -2
  255. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +2 -1
  256. package/src/fabric/ScreenStackNativeComponent.ts +1 -1
  257. package/src/gesture-handler/GestureDetectorProvider.tsx +2 -2
  258. package/src/gesture-handler/ScreenGestureDetector.tsx +4 -4
  259. package/src/gesture-handler/fabricUtils.ts +74 -27
  260. package/src/index.tsx +11 -37
  261. package/src/native-stack/navigators/createNativeStackNavigator.tsx +3 -0
  262. package/src/native-stack/types.tsx +60 -17
  263. package/src/native-stack/utils/getDefaultHeaderHeight.tsx +1 -1
  264. package/src/native-stack/views/FooterComponent.tsx +1 -1
  265. package/src/native-stack/views/HeaderConfig.tsx +7 -5
  266. package/src/native-stack/views/NativeStackView.tsx +48 -67
  267. package/src/reanimated/ReanimatedNativeStackScreen.tsx +2 -2
  268. package/src/reanimated/ReanimatedScreen.tsx +2 -1
  269. package/src/reanimated/ReanimatedScreenProvider.tsx +2 -1
  270. package/src/types.tsx +72 -15
  271. package/src/utils.ts +27 -5
@@ -27,6 +27,7 @@ import com.swmansion.rnscreens.KeyboardDidHide
27
27
  import com.swmansion.rnscreens.KeyboardNotVisible
28
28
  import com.swmansion.rnscreens.KeyboardState
29
29
  import com.swmansion.rnscreens.KeyboardVisible
30
+ import com.swmansion.rnscreens.NativeDismissalObserver
30
31
  import com.swmansion.rnscreens.R
31
32
  import com.swmansion.rnscreens.Screen
32
33
  import com.swmansion.rnscreens.ScreenContainer
@@ -48,7 +49,8 @@ class DimmingFragment(
48
49
  LifecycleEventObserver,
49
50
  ScreenStackFragmentWrapper,
50
51
  Animation.AnimationListener,
51
- OnApplyWindowInsetsListener {
52
+ OnApplyWindowInsetsListener,
53
+ NativeDismissalObserver {
52
54
  private lateinit var dimmingView: DimmingView
53
55
  private lateinit var containerView: GestureTransparentViewGroup
54
56
 
@@ -65,8 +67,15 @@ class DimmingFragment(
65
67
  private val insetsProxy = InsetsObserverProxy
66
68
 
67
69
  init {
68
- // We register for our child lifecycle as we want to know when it's dismissed via native gesture
69
- nestedFragment.fragment.lifecycle.addObserver(this)
70
+ assert(
71
+ nestedFragment.fragment is ScreenStackFragment,
72
+ ) { "[RNScreens] Dimming fragment is intended for use only with ScreenStackFragment" }
73
+ val fragment = nestedFragment.fragment as ScreenStackFragment
74
+
75
+ // We register for our child lifecycle as we want to know when it starts, because bottom sheet
76
+ // behavior is attached only then & we want to attach our own callbacks to it.
77
+ fragment.lifecycle.addObserver(this)
78
+ fragment.nativeDismissalObserver = this
70
79
  }
71
80
 
72
81
  /**
@@ -111,8 +120,8 @@ class DimmingFragment(
111
120
  computeOffsetFromDetentIndex(
112
121
  (screen.sheetLargestUndimmedDetentIndex + 1).coerceIn(
113
122
  0,
114
- screen.sheetDetents.count() - 1
115
- )
123
+ screen.sheetDetents.count() - 1,
124
+ ),
116
125
  )
117
126
  assert(firstDimmedOffset >= largestUndimmedOffset) {
118
127
  "[RNScreens] Invariant violation: firstDimmedOffset ($firstDimmedOffset) < largestDimmedOffset ($largestUndimmedOffset)"
@@ -173,7 +182,7 @@ class DimmingFragment(
173
182
  // We want dimming view to have always fade animation in current usages.
174
183
  AnimationUtils.loadAnimation(
175
184
  context,
176
- if (enter) R.anim.rns_fade_in else R.anim.rns_fade_out
185
+ if (enter) R.anim.rns_fade_in else R.anim.rns_fade_out,
177
186
  )
178
187
 
179
188
  override fun onCreateView(
@@ -226,10 +235,6 @@ class DimmingFragment(
226
235
  }
227
236
  }
228
237
 
229
- Lifecycle.Event.ON_STOP -> {
230
- dismissSelf(emitDismissedEvent = true)
231
- }
232
-
233
238
  else -> {}
234
239
  }
235
240
  }
@@ -350,13 +355,9 @@ class DimmingFragment(
350
355
  nestedFragment.onViewAnimationEnd()
351
356
  }
352
357
 
353
- override fun tryGetActivity(): Activity? {
354
- return activity
355
- }
358
+ override fun tryGetActivity(): Activity? = activity
356
359
 
357
- override fun tryGetContext(): ReactContext? {
358
- return context as? ReactContext?
359
- }
360
+ override fun tryGetContext(): ReactContext? = context as? ReactContext?
360
361
 
361
362
  override val fragment: Fragment
362
363
  get() = this
@@ -417,7 +418,7 @@ class DimmingFragment(
417
418
  screen.sheetBehavior?.let {
418
419
  (nestedFragment as ScreenStackFragment).configureBottomSheetBehaviour(
419
420
  it,
420
- KeyboardVisible(imeInset.bottom)
421
+ KeyboardVisible(imeInset.bottom),
421
422
  )
422
423
  }
423
424
 
@@ -457,12 +458,12 @@ class DimmingFragment(
457
458
  if (isKeyboardVisible) {
458
459
  (nestedFragment as ScreenStackFragment).configureBottomSheetBehaviour(
459
460
  it,
460
- KeyboardDidHide
461
+ KeyboardDidHide,
461
462
  )
462
463
  } else if (keyboardState != KeyboardNotVisible) {
463
464
  (nestedFragment as ScreenStackFragment).configureBottomSheetBehaviour(
464
465
  it,
465
- KeyboardNotVisible
466
+ KeyboardNotVisible,
466
467
  )
467
468
  } else {
468
469
  }
@@ -485,4 +486,8 @@ class DimmingFragment(
485
486
  ).build()
486
487
  }
487
488
  }
489
+
490
+ override fun onNativeDismiss(dismissed: ScreenStackFragmentWrapper) {
491
+ dismissSelf(emitDismissedEvent = true)
492
+ }
488
493
  }
@@ -5,6 +5,7 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPS
5
5
  import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED
6
6
  import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HALF_EXPANDED
7
7
  import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN
8
+ import com.swmansion.rnscreens.Screen
8
9
 
9
10
  object SheetUtils {
10
11
  /**
@@ -125,3 +126,10 @@ object SheetUtils {
125
126
  return false
126
127
  }
127
128
  }
129
+
130
+ fun Screen.isSheetFitToContents(): Boolean =
131
+ stackPresentation === Screen.StackPresentation.FORM_SHEET &&
132
+ sheetDetents.count() == 1 &&
133
+ sheetDetents.first() == Screen.SHEET_FIT_TO_CONTENTS
134
+
135
+ fun Screen.usesFormSheetPresentation(): Boolean = stackPresentation === Screen.StackPresentation.FORM_SHEET
@@ -3,6 +3,9 @@ package com.swmansion.rnscreens.ext
3
3
  import android.graphics.drawable.ColorDrawable
4
4
  import android.view.View
5
5
  import android.view.ViewGroup
6
+ import com.facebook.react.views.scroll.ReactHorizontalScrollView
7
+ import com.facebook.react.views.scroll.ReactScrollView
8
+ import com.swmansion.rnscreens.ScreenStack
6
9
 
7
10
  internal fun View.parentAsView() = this.parent as? View
8
11
 
@@ -30,3 +33,24 @@ internal fun View.maybeBgColor(): Int? {
30
33
  }
31
34
  return null
32
35
  }
36
+
37
+ internal fun View.isInsideScrollViewWithRemoveClippedSubviews(): Boolean {
38
+ if (this is ReactHorizontalScrollView || this is ReactScrollView) {
39
+ return false
40
+ }
41
+ var parentView = this.parent
42
+ while (parentView is ViewGroup && parentView !is ScreenStack) {
43
+ when (parentView) {
44
+ is ReactHorizontalScrollView -> {
45
+ return parentView.removeClippedSubviews
46
+ }
47
+ is ReactScrollView -> {
48
+ return parentView.removeClippedSubviews
49
+ }
50
+ else -> {
51
+ parentView = parentView.parent
52
+ }
53
+ }
54
+ }
55
+ return false
56
+ }
@@ -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,11 +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) {
312
+ [self maybeAssertActivityStateProgressionOldValue:_activityState newValue:activityState];
307
313
  _activityState = activityState;
308
314
  [_reactSuperview markChildUpdated];
309
315
  }
310
316
  }
311
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
+
312
331
  #if !TARGET_OS_TV && !TARGET_OS_VISION
313
332
  - (void)setStatusBarStyle:(RNSStatusBarStyle)statusBarStyle
314
333
  {
@@ -745,6 +764,12 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
745
764
  self.controller.modalPresentationStyle == UIModalPresentationOverCurrentContext;
746
765
  }
747
766
 
767
+ - (void)invalidate
768
+ {
769
+ _controller = nil;
770
+ [_sheetsScrollView removeObserver:self forKeyPath:@"bounds" context:nil];
771
+ }
772
+
748
773
  #if !TARGET_OS_TV && !TARGET_OS_VISION
749
774
 
750
775
  - (void)setPropertyForSheet:(UISheetPresentationController *)sheet
@@ -1072,6 +1097,11 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
1072
1097
  return _config != nil;
1073
1098
  }
1074
1099
 
1100
+ - (void)willBeUnmountedInUpcomingTransaction
1101
+ {
1102
+ _markedForUnmountInCurrentTransaction = YES;
1103
+ }
1104
+
1075
1105
  + (react::ComponentDescriptorProvider)componentDescriptorProvider
1076
1106
  {
1077
1107
  return react::concreteComponentDescriptorProvider<react::RNSScreenComponentDescriptor>();
@@ -1261,11 +1291,6 @@ constexpr NSInteger SHEET_LARGEST_UNDIMMED_DETENT_NONE = -1;
1261
1291
  // subviews
1262
1292
  }
1263
1293
 
1264
- - (void)invalidate
1265
- {
1266
- _controller = nil;
1267
- [_sheetsScrollView removeObserver:self forKeyPath:@"bounds" context:nil];
1268
- }
1269
1294
  #endif
1270
1295
 
1271
1296
  @end