callstack / callstack/react-native-pager-view

Incorrect page change detected when scrolling outside of view

Abierto
#590 1 comentario 3 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
3.4k
Forks
476
Merge medio
10 d 21 h
PR fusionados (30 d)
2

Descripción

## Environment
package | version
-- | --
react-native-tab-view | 3.1.1
react-native-pager-view | 5.4.9
react-native | 0.64.3
expo | 44.0.0
node | 12.13.0
npm or yarn | yarn@v1.22.18

## Description

Using [react-native-tab-view](https://github.com/satya164/react-native-tab-view), we have a `TabView` and a sidebar to the side of it. When you swipe on the `TabView` and drag it over the sidebar it registers a page switch but it doesn't handle it properly so no page selected event is emitted. The code around this is based in `react-native-pager-view`.

Also reported in that repo, https://github.com/satya164/react-native-tab-view/issues/1365.

### Current behavior

I have a `TabView` alongside a sidebar. When a swipe is started on the view and is released at edge of the sidebar, the tab index doesn't change (`onIndexChange()` isn't called) but the tab still changes. This leaves the tabs in an incorrect state and some of the tabs can't be switched to.

https://user-images.githubusercontent.com/84314259/175305002-1deba6e6-e71e-43ac-ad46-c3b11382364a.mp4

### Expected behavior

When a full swipe happens then the tab is changed correctly. Perhaps once the swipe leaves the view then it counts it as swiped, rather than waiting until the swipe is released.

## Reproducible Demo
I've forked the `react-native-tab-view` repo and added the sidebar to the example code.

[aaulthudl/react-native-tab-view](https://github.com/aaulthudl/react-native-tab-view)

## Patch Fix
We've added a patch using `patch-package` to automatically switch pages properly when the swipe leaves the container. It doesn't have a bounce animation when switching pages though.

```patch
diff --git a/node_modules/react-native-pager-view/.DS_Store b/node_modules/react-native-pager-view/.DS_Store
new file mode 100644
index 0000000..7083c2c
Binary files /dev/null and b/node_modules/react-native-pager-view/.DS_Store differ
diff --git a/node_modules/react-native-pager-view/ios/.DS_Store b/node_modules/react-native-pager-view/ios/.DS_Store
new file mode 100644
index 0000000..40daf43
Binary files /dev/null and b/node_modules/react-native-pager-view/ios/.DS_Store differ
diff --git a/node_modules/react-native-pager-view/ios/ReactNativePageView.m b/node_modules/react-native-pager-view/ios/ReactNativePageView.m
index 9f8ed5b..8ddad58 100644
--- a/node_modules/react-native-pager-view/ios/ReactNativePageView.m
+++ b/node_modules/react-native-pager-view/ios/ReactNativePageView.m
@@ -476,6 +476,16 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat contentOffset =[self isHorizontal] ? scrollView.contentOffset.x : scrollView.contentOffset.y;
CGFloat topBound = [self isHorizontal] ? scrollView.bounds.size.width : scrollView.bounds.size.height;

+ // If a drag goes outside of the content container it should end the drag
+ CGFloat lastContentOffset = [self isHorizontal] ? self.lastContentOffset.x : self.lastContentOffset.y;
+ if (contentOffset <= 0 && lastContentOffset != 0) {
+ scrollView.scrollEnabled = NO;
+ scrollView.scrollEnabled = YES;
+
+ [self goTo:position animated:YES];
+ return;
+ }
+
if ((isFirstPage && contentOffset <= topBound) || (isLastPage && contentOffset >= topBound)) {
CGPoint croppedOffset = [self isHorizontal] ? CGPointMake(topBound, 0) : CGPointMake(0, topBound);
scrollView.contentOffset = croppedOffset;
```

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

Comienza en ios/ReactNativePageView.m, especialmente en scrollViewDidScroll, y compara el comportamiento observado con el patch proporcionado y la reproducción enlazada. Reproduce un deslizamiento que deje el pager junto a la barra lateral y, después, verifica que el índice de la pestaña y onIndexChange sigan sincronizados, incluido el comportamiento en los extremos y al rebotar.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
ios, objective-c, react-native
Área
mobile
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.