Skip to content

Commit ef4b7da

Browse files
authored
Merge pull request #919 from callstack/fix/#722/scroll-view-issue
fix(#722): revert not working back navigation gesture in favour of PagerView inside ScrollView
2 parents 5adce4f + 0cf7d6f commit ef4b7da

File tree

4 files changed

+59
-61
lines changed

4 files changed

+59
-61
lines changed

Diff for: example/src/App.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack';
3636
import { SafeAreaProvider } from 'react-native-safe-area-context';
3737
import { NextBasicPagerViewExample } from './NextBasicPagerViewExample';
3838
import { PagerHookExample } from './PagerHookExample';
39+
import { NestedTabViewExample } from './tabView/NestedTabViewExample';
3940

4041
const examples = [
42+
{ component: NestedTabViewExample, name: 'Nested TabView Example' },
4143
{ component: BasicPagerViewExample, name: 'Basic Example' },
4244
{ component: PagerHookExample, name: 'Pager Hook Example' },
4345
{ component: KeyboardExample, name: 'Keyboard Example' },

Diff for: example/src/tabView/NestedTabViewExample.tsx

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import * as React from 'react';
2+
import { View, useWindowDimensions, Text, ScrollView } from 'react-native';
3+
import { TabView, SceneMap } from 'react-native-tab-view';
4+
import { Header } from 'react-native/Libraries/NewAppScreen';
5+
6+
function FirstRoute() {
7+
return (
8+
<View style={{ flex: 1, padding: 20, backgroundColor: 'blue' }}>
9+
<Text style={{color: 'white'}}>First Route</Text>
10+
</View>
11+
);
12+
}
13+
14+
function SecondRoute() {
15+
return (
16+
<View style={{ flex: 1, padding: 20, backgroundColor: 'purple' }}>
17+
<Text style={{color: 'white'}}>Second Route</Text>
18+
</View>
19+
);
20+
}
21+
22+
const renderScene = SceneMap({
23+
first: FirstRoute,
24+
second: SecondRoute,
25+
});
26+
27+
const routes = [
28+
{ key: 'first', title: 'First' },
29+
{ key: 'second', title: 'Second' },
30+
];
31+
32+
export function NestedTabViewExample() {
33+
const layout = useWindowDimensions();
34+
const [index, setIndex] = React.useState(0);
35+
36+
return (
37+
<ScrollView
38+
contentContainerStyle={{flexGrow: 1, backgroundColor: 'red'}}
39+
nestedScrollEnabled={false}
40+
scrollEnabled={true}
41+
>
42+
<Header />
43+
44+
<View>
45+
<TabView
46+
style={{height: 1200}}
47+
navigationState={{ index, routes }}
48+
renderScene={renderScene}
49+
onIndexChange={setIndex}
50+
initialLayout={{ width: layout.width }}
51+
/>
52+
</View>
53+
</ScrollView>
54+
);
55+
}

Diff for: ios/LEGACY/Fabric/LEGACY_RNCPagerViewComponentView.mm

+1-32
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414

1515
using namespace facebook::react;
1616

17-
@interface LEGACY_RNCPagerViewComponentView () <RCTLEGACY_RNCViewPagerViewProtocol, UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIScrollViewDelegate, UIGestureRecognizerDelegate>
18-
19-
@property(nonatomic, assign) UIPanGestureRecognizer* panGestureRecognizer;
17+
@interface LEGACY_RNCPagerViewComponentView () <RCTLEGACY_RNCViewPagerViewProtocol, UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIScrollViewDelegate>
2018

2119
@end
2220

@@ -71,11 +69,6 @@ - (instancetype)initWithFrame:(CGRect)frame
7169
_destinationIndex = -1;
7270
_layoutDirection = @"ltr";
7371
_overdrag = NO;
74-
UIPanGestureRecognizer* panGestureRecognizer = [UIPanGestureRecognizer new];
75-
self.panGestureRecognizer = panGestureRecognizer;
76-
panGestureRecognizer.delegate = self;
77-
[self addGestureRecognizer: panGestureRecognizer];
78-
7972
}
8073

8174
return self;
@@ -409,30 +402,6 @@ + (ComponentDescriptorProvider)componentDescriptorProvider
409402
return concreteComponentDescriptorProvider<LEGACY_RNCViewPagerComponentDescriptor>();
410403
}
411404

412-
413-
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
414-
415-
// Recognize simultaneously only if the other gesture is RN Screen's pan gesture (one that is used to perform fullScreenGestureEnabled)
416-
if (gestureRecognizer == self.panGestureRecognizer && [NSStringFromClass([otherGestureRecognizer class]) isEqual: @"RNSPanGestureRecognizer"]) {
417-
UIPanGestureRecognizer* panGestureRecognizer = (UIPanGestureRecognizer*) gestureRecognizer;
418-
CGPoint velocity = [panGestureRecognizer velocityInView:self];
419-
BOOL isLTR = [self isLtrLayout];
420-
BOOL isBackGesture = (isLTR && velocity.x > 0) || (!isLTR && velocity.x < 0);
421-
422-
if (self.currentIndex == 0 && isBackGesture) {
423-
scrollView.panGestureRecognizer.enabled = false;
424-
} else {
425-
const auto &viewProps = *std::static_pointer_cast<const LEGACY_RNCViewPagerProps>(_props);
426-
scrollView.panGestureRecognizer.enabled = viewProps.scrollEnabled;
427-
}
428-
429-
return YES;
430-
}
431-
const auto &viewProps = *std::static_pointer_cast<const LEGACY_RNCViewPagerProps>(_props);
432-
scrollView.panGestureRecognizer.enabled = viewProps.scrollEnabled;
433-
return NO;
434-
}
435-
436405
@end
437406

438407
Class<RCTComponentViewProtocol> LEGACY_RNCViewPagerCls(void)

Diff for: ios/LEGACY/LEGACY_RNCPagerView.m

+1-29
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
#import "RCTOnPageSelected.h"
99
#import <math.h>
1010

11-
@interface LEGACY_RNCPagerView () <UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIScrollViewDelegate, UIGestureRecognizerDelegate>
12-
13-
@property(nonatomic, assign) UIPanGestureRecognizer* panGestureRecognizer;
11+
@interface LEGACY_RNCPagerView () <UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIScrollViewDelegate>
1412

1513
@property(nonatomic, strong) UIPageViewController *reactPageViewController;
1614
@property(nonatomic, strong) RCTEventDispatcher *eventDispatcher;
@@ -48,10 +46,6 @@ - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher {
4846
_cachedControllers = [NSHashTable hashTableWithOptions:NSHashTableStrongMemory];
4947
_overdrag = NO;
5048
_layoutDirection = @"ltr";
51-
UIPanGestureRecognizer* panGestureRecognizer = [UIPanGestureRecognizer new];
52-
self.panGestureRecognizer = panGestureRecognizer;
53-
panGestureRecognizer.delegate = self;
54-
[self addGestureRecognizer: panGestureRecognizer];
5549
}
5650
return self;
5751
}
@@ -474,28 +468,6 @@ - (NSString *)determineScrollDirection:(UIScrollView *)scrollView {
474468
return scrollDirection;
475469
}
476470

477-
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
478-
479-
// Recognize simultaneously only if the other gesture is RN Screen's pan gesture (one that is used to perform fullScreenGestureEnabled)
480-
if (gestureRecognizer == self.panGestureRecognizer && [NSStringFromClass([otherGestureRecognizer class]) isEqual: @"RNSPanGestureRecognizer"]) {
481-
UIPanGestureRecognizer* panGestureRecognizer = (UIPanGestureRecognizer*) gestureRecognizer;
482-
CGPoint velocity = [panGestureRecognizer velocityInView:self];
483-
BOOL isLTR = [self isLtrLayout];
484-
BOOL isBackGesture = (isLTR && velocity.x > 0) || (!isLTR && velocity.x < 0);
485-
486-
if (self.currentIndex == 0 && isBackGesture) {
487-
self.scrollView.panGestureRecognizer.enabled = false;
488-
} else {
489-
self.scrollView.panGestureRecognizer.enabled = self.scrollEnabled;
490-
}
491-
492-
return YES;
493-
}
494-
495-
self.scrollView.panGestureRecognizer.enabled = self.scrollEnabled;
496-
return NO;
497-
}
498-
499471
- (BOOL)isLtrLayout {
500472
return [_layoutDirection isEqualToString:@"ltr"];
501473
}

0 commit comments

Comments
 (0)