Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion TestsExample/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react';
import {enableFreeze} from 'react-native-screens';
import {ReanimatedScreenProvider} from 'react-native-screens/reanimated';

import TestModalPresentation from './src/test-modal-presentation';
import Test42 from './src/Test42';
import Test111 from './src/Test111';
import Test263 from './src/Test263';
Expand Down Expand Up @@ -84,7 +85,7 @@ enableFreeze(true);
export default function App() {
return (
<ReanimatedScreenProvider>
<Test42 />
<TestModalPresentation />
</ReanimatedScreenProvider>
);
}
3 changes: 2 additions & 1 deletion TestsExample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
"@react-navigation/bottom-tabs": "^6.3.1",
"@react-navigation/drawer": "^6.4.1",
"@react-navigation/native": "^6.0.10",
"@react-navigation/native-stack": "^6.7.0",
"@react-navigation/stack": "^6.2.1",
"nanoid": "^3.2.0",
"postinstall-postinstall": "^2.1.0",
"react": "18.0.0",
"react-native": "0.69.0",
"postinstall-postinstall": "^2.1.0",
"react-native-gesture-handler": "^2.5.0",
"react-native-reanimated": "2.9.1",
"react-native-safe-area-context": "^4.0.1-rc.5",
Expand Down
9 changes: 9 additions & 0 deletions TestsExample/src/test-modal-presentation/ModalGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import StackBuilder from './StackBuilder';
import Modals from './modals';


export default StackBuilder(Modals, {
headerShown: false,
animation: 'fade_from_bottom',
presentation: 'containedTransparentModal',
});
11 changes: 11 additions & 0 deletions TestsExample/src/test-modal-presentation/ScreenGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import StackBuilder from './StackBuilder';
import Screens from './screens';


export default StackBuilder(Screens, {
headerShadowVisible: false,
headerTintColor: 'black',
headerBackTitleVisible: false,
fullScreenGestureEnabled: true,
contentStyle: { backgroundColor: 'white' },
});
16 changes: 16 additions & 0 deletions TestsExample/src/test-modal-presentation/StackBuilder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { createNativeStackNavigator, NativeStackNavigationOptions } from '@react-navigation/native-stack';

export const NativeStack = createNativeStackNavigator();

export default (configs: any, groupOptions?: NativeStackNavigationOptions) => {
return () => (
<NativeStack.Group screenOptions={groupOptions}>
{configs.map(config => {
const { options, ...anyConfig } = config;
const { statusBarStyle, statusBarAnimation, statusBarHidden, ...anyOption } = options || {};
return <NativeStack.Screen key={config.name} {...anyConfig} options={anyOption} />;
})}
</NativeStack.Group>
);
};
19 changes: 19 additions & 0 deletions TestsExample/src/test-modal-presentation/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import {
NavigationContainer as NavigationContainerNative,
} from '@react-navigation/native';

import ModalGroup from './ModalGroup';
import ScreenGroup from './ScreenGroup';
import { NativeStack } from './StackBuilder';

export default function TestModalPresentation() {
return (
<NavigationContainerNative>
<NativeStack.Navigator>
{ScreenGroup()}
{ModalGroup()}
</NativeStack.Navigator>
</NavigationContainerNative>
);
}
17 changes: 17 additions & 0 deletions TestsExample/src/test-modal-presentation/modals/ModalA.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { Button, Text, View } from 'react-native';

type Props = {};

export default function ModalA(props: Props) {
return (
<View style={{ flex: 1, backgroundColor: 'rgba(255,0,0,0.6)',alignItems: 'center', justifyContent: 'center'}}>
<View style={{backgroundColor: 'white'}}>

<Text>ModalA, with opacity and backgroundColor</Text>
<Text>At ModalA, we still can gesture swipe the screenB back to screenA, </Text>
<Button title={"pop modal"} onPress={() => props.navigation.pop()} />
</View>
</View>
);
}
9 changes: 9 additions & 0 deletions TestsExample/src/test-modal-presentation/modals/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import ModalA from './ModalA';

export default [
{
name: 'modalA',
component: ModalA,
options: { animation: 'fade' },
}
]
11 changes: 11 additions & 0 deletions TestsExample/src/test-modal-presentation/screens/ScreenA.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import { Button, Text, View } from 'react-native';

export default function ScreenA({navigation}) {
return (
<View style={{flex:1, backgroundColor: 'blue', alignItems: 'center', justifyContent: 'center'}} >
<Text style={{color: 'white'}}>ScreenA, with backgroundColor: 'blue'</Text>
<Button title={"navigate to: Screen B"} onPress={() => navigation.navigate('screenB')} />
</View>
);
}
12 changes: 12 additions & 0 deletions TestsExample/src/test-modal-presentation/screens/ScreenB.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { Button, Text, View } from 'react-native';


export default function ScreenB({navigation}) {
return (
<View style={{flex:1, backgroundColor: 'cyan', alignItems: 'center', justifyContent: 'center'}} >
<Text>ScreenB, with backgroundColor: 'cyan'</Text>
<Button title={"navigate to: Modal A"} onPress={() => navigation.navigate('modalA')} />
</View>
);
}
12 changes: 12 additions & 0 deletions TestsExample/src/test-modal-presentation/screens/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import ScreenA from './ScreenA';
import ScreenB from './ScreenB';
export default [
{
name: 'screenA',
component: ScreenA,
},
{
name: 'screenB',
component: ScreenB,
}
]
13 changes: 13 additions & 0 deletions TestsExample/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1388,6 +1388,19 @@
resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.3.tgz#9f56b650a9a1a8263a271628be7342c8121d1788"
integrity sha512-Lv2lR7si5gNME8dRsqz57d54m4FJtrwHRjNQLOyQO546ZxO+g864cSvoLC6hQedQU0+IJnPTsZiEI2hHqfpEpw==

"@react-navigation/elements@^1.3.4":
version "1.3.4"
resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.4.tgz#abb48136508c1e60862dc14a101ce02ff685a337"
integrity sha512-O0jICpjn3jskVo4yiWzZozmj7DZy1ZBbn3O7dbenuUjZSj/cscjwaapmZZFGcI/IMmjmx8UTKsybhCFEIbGf3g==

"@react-navigation/native-stack@^6.7.0":
version "6.7.0"
resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-6.7.0.tgz#57e6390e3e4e46b3a7f580810c3d384b4676b7e5"
integrity sha512-03CuSwbBvP9+iXgjrTRRw+aog+KZXbhPzqCWVExzIWNOzf5/PJEcdtlm9KDrx2aHHDtDA6LRLKQA4UIlJOmNzA==
dependencies:
"@react-navigation/elements" "^1.3.4"
warn-once "^0.1.0"

"@react-navigation/native@^6.0.10":
version "6.0.10"
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.0.10.tgz#c58aa176eb0e63f3641c83a65c509faf253e4385"
Expand Down
17 changes: 17 additions & 0 deletions ios/RNSScreenStack.mm
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,17 @@ - (void)cancelTouchesInParent
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view;
RNSScreenView *topModal = (RNSScreenView *)_presentedModals.lastObject.view;

if (![topScreen isKindOfClass:[RNSScreenView class]] || !topScreen.gestureEnabled ||
_controller.viewControllers.count < 2) {
return NO;
}

BOOL isAttached = topModal.controller.presentingViewController != nil;
if (topModal.controller == topScreen.controller.presentedViewController && isAttached) {
return NO;
}

#if TARGET_OS_TV
[self cancelTouchesInParent];
Expand Down Expand Up @@ -820,12 +831,18 @@ - (BOOL)isScrollViewPanGestureRecognizer:(UIGestureRecognizer *)gestureRecognize
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveEvent:(UIEvent *)event
{
RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view;
RNSScreenView *topModal = (RNSScreenView *)_presentedModals.lastObject.view;

if (![topScreen isKindOfClass:[RNSScreenView class]] || !topScreen.gestureEnabled ||
_controller.viewControllers.count < 2) {
return NO;
}

BOOL isAttached = topModal.controller.presentingViewController != nil;
if (topModal.controller == topScreen.controller.presentedViewController && isAttached) {
return NO;
}

// We want to pass events to RNSPanGestureRecognizer iff full screen swipe is enabled.
if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizer class]]) {
return topScreen.fullScreenSwipeEnabled;
Expand Down