Skip to content

Commit 1240144

Browse files
committed
fix(iOS, Paper): possibility of infinite loop when swiping back in nested stack (#2223)
## Description In #2193 I've made a mistake - on Paper, when there is no touch handler held in `_touchHandler` field I've started lookup for touch handler in ancestor chain from `self` -> which leads to infinite loop when swiping back in nested-stack navigation scenario. ## Changes * Started lookup from superview. ## Test code and steps to reproduce `Test2223` 1. Navigate to NestedStack. 2. Navigate to NestedStack details screen. 3. Use swipe gesture to go-back W/o this PR the application will crash hitting infinite loop. Also test that this behaviour remains fixed: * software-mansion/react-native-screens#2131 ## Checklist - [x] Included code example that can be used to test this change - [x] Ensured that CI passes
1 parent 80bcacd commit 1240144

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

apps/test-examples/App.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ import Test2048 from './src/Test2048';
103103
import Test2069 from './src/Test2069';
104104
import Test2118 from './src/Test2118';
105105
import Test2184 from './src/Test2184';
106+
import Test2223 from './src/Test2223';
106107
import TestScreenAnimation from './src/TestScreenAnimation';
107108
import TestHeader from './src/TestHeader';
108109

apps/test-examples/src/Test2223.tsx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import React from 'react';
2+
import { View, Text, Button, Pressable, StyleSheet, Alert } from 'react-native';
3+
import { NavigationContainer, useNavigation } from '@react-navigation/native';
4+
import { createNativeStackNavigator } from '@react-navigation/native-stack';
5+
6+
const Stack = createNativeStackNavigator();
7+
const NestedStack = createNativeStackNavigator();
8+
9+
export default function App() {
10+
return (
11+
<NavigationContainer>
12+
<Stack.Navigator screenOptions={{ animation: 'slide_from_left' }}>
13+
<Stack.Screen name="Home" component={HomeScreen} />
14+
<Stack.Screen name="DetailsStack" component={DetailsScreen} />
15+
<Stack.Screen name="NestedStack" component={NestedStackScreen} />
16+
</Stack.Navigator>
17+
</NavigationContainer>
18+
);
19+
}
20+
21+
function NestedStackScreen() {
22+
return (
23+
<NestedStack.Navigator>
24+
<NestedStack.Screen name="NSHome" component={HomeScreen} />
25+
<NestedStack.Screen name="NSDetailsStack" component={DetailsScreen} />
26+
</NestedStack.Navigator>
27+
);
28+
}
29+
30+
function HomeScreen() {
31+
const navigation = useNavigation();
32+
return (
33+
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
34+
<Text>Home Screen</Text>
35+
<Button
36+
title="Go to Details"
37+
onPress={() => navigation.navigate('DetailsStack')}
38+
/>
39+
<Button
40+
title="Go to NestedStack"
41+
onPress={() => navigation.navigate('NestedStack')}
42+
/>
43+
<Button
44+
title="Go to NestedStack Details"
45+
onPress={() => navigation.navigate('NSDetailsStack')}
46+
/>
47+
</View>
48+
);
49+
}
50+
51+
function DetailsScreen() {
52+
return (
53+
<View style={{ flex: 1, alignItems: 'center' }}>
54+
{new Array(10).fill(0).map((_, i) => (
55+
<Pressable
56+
key={i.toString()}
57+
onPress={() => {
58+
Alert.alert('Pressed!');
59+
}}
60+
style={({ pressed }) => [
61+
{
62+
backgroundColor: pressed ? 'rgb(210, 230, 255)' : 'white',
63+
},
64+
styles.wrapperCustom,
65+
]}>
66+
{({ pressed }) => (
67+
<Text style={styles.text}>{pressed ? 'Pressed!' : 'Press Me'}</Text>
68+
)}
69+
</Pressable>
70+
))}
71+
</View>
72+
);
73+
}
74+
75+
const styles = StyleSheet.create({
76+
wrapperCustom: {
77+
width: '100%',
78+
height: 100,
79+
marginHorizontal: 30,
80+
borderRadius: 10,
81+
margin: 10,
82+
},
83+
text: {
84+
fontSize: 20,
85+
color: 'black',
86+
},
87+
});
88+

ios/utils/UIView+RNSUtility.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ @implementation UIView (RNSUtility)
99

1010
- (nullable RNS_TOUCH_HANDLER_ARCH_TYPE *)rnscreens_findTouchHandlerInAncestorChain
1111
{
12-
UIView *parent = self;
12+
UIView *parent = self.superview;
1313

1414
#ifdef RCT_NEW_ARCH_ENABLED
1515
// On Fabric there is no view that exposes touchHandler above us in the view hierarchy, however it is still

0 commit comments

Comments
 (0)