diff --git a/example/src/App.tsx b/example/src/App.tsx index eae7e5b7..5e60f973 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -36,10 +36,8 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import { NextBasicPagerViewExample } from './NextBasicPagerViewExample'; import { PagerHookExample } from './PagerHookExample'; -import { NestedTabViewExample } from './tabView/NestedTabViewExample'; const examples = [ - { component: NestedTabViewExample, name: 'Nested TabView Example' }, { component: BasicPagerViewExample, name: 'Basic Example' }, { component: PagerHookExample, name: 'Pager Hook Example' }, { component: KeyboardExample, name: 'Keyboard Example' }, diff --git a/example/src/tabView/NestedTabViewExample.tsx b/example/src/tabView/NestedTabViewExample.tsx deleted file mode 100644 index 92418797..00000000 --- a/example/src/tabView/NestedTabViewExample.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import * as React from 'react'; -import { View, useWindowDimensions, Text, ScrollView } from 'react-native'; -import { TabView, SceneMap } from 'react-native-tab-view'; -import { Header } from 'react-native/Libraries/NewAppScreen'; - -function FirstRoute() { - return ( - - First Route - - ); -} - -function SecondRoute() { - return ( - - Second Route - - ); -} - -const renderScene = SceneMap({ - first: FirstRoute, - second: SecondRoute, -}); - -const routes = [ - { key: 'first', title: 'First' }, - { key: 'second', title: 'Second' }, -]; - -export function NestedTabViewExample() { - const layout = useWindowDimensions(); - const [index, setIndex] = React.useState(0); - - return ( - -
- - - - - - ); -} diff --git a/ios/LEGACY/Fabric/LEGACY_RNCPagerViewComponentView.mm b/ios/LEGACY/Fabric/LEGACY_RNCPagerViewComponentView.mm index 3fe41115..cdeece93 100644 --- a/ios/LEGACY/Fabric/LEGACY_RNCPagerViewComponentView.mm +++ b/ios/LEGACY/Fabric/LEGACY_RNCPagerViewComponentView.mm @@ -14,7 +14,9 @@ using namespace facebook::react; -@interface LEGACY_RNCPagerViewComponentView () +@interface LEGACY_RNCPagerViewComponentView () + +@property(nonatomic, assign) UIPanGestureRecognizer* panGestureRecognizer; @end @@ -69,6 +71,11 @@ - (instancetype)initWithFrame:(CGRect)frame _destinationIndex = -1; _layoutDirection = @"ltr"; _overdrag = NO; + UIPanGestureRecognizer* panGestureRecognizer = [UIPanGestureRecognizer new]; + self.panGestureRecognizer = panGestureRecognizer; + panGestureRecognizer.delegate = self; + [self addGestureRecognizer: panGestureRecognizer]; + } return self; @@ -402,6 +409,30 @@ + (ComponentDescriptorProvider)componentDescriptorProvider return concreteComponentDescriptorProvider(); } + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { + + // Recognize simultaneously only if the other gesture is RN Screen's pan gesture (one that is used to perform fullScreenGestureEnabled) + if (gestureRecognizer == self.panGestureRecognizer && [NSStringFromClass([otherGestureRecognizer class]) isEqual: @"RNSPanGestureRecognizer"]) { + UIPanGestureRecognizer* panGestureRecognizer = (UIPanGestureRecognizer*) gestureRecognizer; + CGPoint velocity = [panGestureRecognizer velocityInView:self]; + BOOL isLTR = [self isLtrLayout]; + BOOL isBackGesture = (isLTR && velocity.x > 0) || (!isLTR && velocity.x < 0); + + if (self.currentIndex == 0 && isBackGesture) { + scrollView.panGestureRecognizer.enabled = false; + } else { + const auto &viewProps = *std::static_pointer_cast(_props); + scrollView.panGestureRecognizer.enabled = viewProps.scrollEnabled; + } + + return YES; + } + const auto &viewProps = *std::static_pointer_cast(_props); + scrollView.panGestureRecognizer.enabled = viewProps.scrollEnabled; + return NO; +} + @end Class LEGACY_RNCViewPagerCls(void) diff --git a/ios/LEGACY/LEGACY_RNCPagerView.m b/ios/LEGACY/LEGACY_RNCPagerView.m index 17913255..492a8641 100644 --- a/ios/LEGACY/LEGACY_RNCPagerView.m +++ b/ios/LEGACY/LEGACY_RNCPagerView.m @@ -8,7 +8,9 @@ #import "RCTOnPageSelected.h" #import -@interface LEGACY_RNCPagerView () +@interface LEGACY_RNCPagerView () + +@property(nonatomic, assign) UIPanGestureRecognizer* panGestureRecognizer; @property(nonatomic, strong) UIPageViewController *reactPageViewController; @property(nonatomic, strong) RCTEventDispatcher *eventDispatcher; @@ -46,6 +48,10 @@ - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher { _cachedControllers = [NSHashTable hashTableWithOptions:NSHashTableStrongMemory]; _overdrag = NO; _layoutDirection = @"ltr"; + UIPanGestureRecognizer* panGestureRecognizer = [UIPanGestureRecognizer new]; + self.panGestureRecognizer = panGestureRecognizer; + panGestureRecognizer.delegate = self; + [self addGestureRecognizer: panGestureRecognizer]; } return self; } @@ -468,6 +474,28 @@ - (NSString *)determineScrollDirection:(UIScrollView *)scrollView { return scrollDirection; } +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { + + // Recognize simultaneously only if the other gesture is RN Screen's pan gesture (one that is used to perform fullScreenGestureEnabled) + if (gestureRecognizer == self.panGestureRecognizer && [NSStringFromClass([otherGestureRecognizer class]) isEqual: @"RNSPanGestureRecognizer"]) { + UIPanGestureRecognizer* panGestureRecognizer = (UIPanGestureRecognizer*) gestureRecognizer; + CGPoint velocity = [panGestureRecognizer velocityInView:self]; + BOOL isLTR = [self isLtrLayout]; + BOOL isBackGesture = (isLTR && velocity.x > 0) || (!isLTR && velocity.x < 0); + + if (self.currentIndex == 0 && isBackGesture) { + self.scrollView.panGestureRecognizer.enabled = false; + } else { + self.scrollView.panGestureRecognizer.enabled = self.scrollEnabled; + } + + return YES; + } + + self.scrollView.panGestureRecognizer.enabled = self.scrollEnabled; + return NO; +} + - (BOOL)isLtrLayout { return [_layoutDirection isEqualToString:@"ltr"]; }