Skip to content

Commit

Permalink
fix: touch event canceled with gesture disabled (#1032)
Browse files Browse the repository at this point in the history
Adds event cancelation only when gesture should be recognized.
  • Loading branch information
Ubax committed Aug 3, 2021
1 parent 3641490 commit faaeb69
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 6 deletions.
50 changes: 50 additions & 0 deletions TestsExample/src/Test1032.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as React from 'react';
import {Alert, Button, Switch, Text, View} from 'react-native';
import {NavigationContainer, ParamListBase} from '@react-navigation/native';
import {
createNativeStackNavigator,
NativeStackNavigationProp,
} from 'react-native-screens/native-stack';

const Stack = createNativeStackNavigator();

export default function App() {
const [gestureEnabled, setGestureEnable] = React.useState(false);
return (
<View style={{flex: 1, paddingBottom: 200}}>
<NavigationContainer>
<Stack.Navigator screenOptions={{gestureEnabled}}>
<Stack.Screen name="Top" component={First} />
<Stack.Screen name="Top1" component={Second} />
</Stack.Navigator>
</NavigationContainer>
<View>
<Text>Gesture enabled</Text>
<Switch value={gestureEnabled} onValueChange={setGestureEnable} />
</View>
</View>
);
}

function First({
navigation,
}: {
navigation: NativeStackNavigationProp<ParamListBase>;
}) {
return (
<View style={{backgroundColor: '#FFF'}}>
<Button
title="Tap me for second screen"
onPress={() => navigation.push('Top1')}
/>
</View>
);
}

function Second() {
return (
<View style={{backgroundColor: '#FFF'}}>
<Button title="Swipe back to see if button click triggers" onPress={() => Alert.alert('Click detected')} />
</View>
);
}
18 changes: 12 additions & 6 deletions ios/RNSScreenStack.m
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ - (void)dismissOnReload
return nil;
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
- (void)cancelTouchesInParent
{
// cancel touches in parent, this is needed to cancel RN touch events. For example when Touchable
// item is close to an edge and we start pulling from edge we want the Touchable to be cancelled.
Expand All @@ -540,13 +540,17 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
[touchHandler cancel];
[touchHandler reset];
}
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view;

if (!topScreen.gestureEnabled || _controller.viewControllers.count < 2) {
return NO;
}
#if TARGET_OS_TV
[self cancelTouchHandlerIfExists];
return YES;
#else
if ([gestureRecognizer isKindOfClass:[RNSGestureRecognizer class]]) {
Expand All @@ -556,13 +560,15 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
((RNSGestureRecognizer *)gestureRecognizer).edges == UIRectEdgeRight) ||
(_controller.view.semanticContentAttribute != UISemanticContentAttributeForceRightToLeft &&
((RNSGestureRecognizer *)gestureRecognizer).edges == UIRectEdgeLeft);
if (isCorrectEdge) {
return topScreen.stackAnimation == RNSScreenStackAnimationSimplePush;
if (isCorrectEdge && topScreen.stackAnimation == RNSScreenStackAnimationSimplePush) {
[self cancelTouchesInParent];
return YES;
}
return NO;
} else {
return topScreen.stackAnimation != RNSScreenStackAnimationSimplePush;
} else if (topScreen.stackAnimation != RNSScreenStackAnimationSimplePush) {
[self cancelTouchesInParent];
return YES;
}
return NO;
#endif
}

Expand Down

0 comments on commit faaeb69

Please sign in to comment.