question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unintended text selection when swiping between tabs

See original GitHub issue

Description

There is an issue with unintended text selection when swiping between tabs. I submitted this to the react-navigation repo (https://github.com/react-navigation/react-navigation/issues/9337) and they asked that I include it over here too, because the issue seems to be related to react-native-gesture-handler, which is one of their dependencies.

Code

import 'react-native-gesture-handler';
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";

const Tab = createMaterialTopTabNavigator();

export default function App() {
    return (
    <NavigationContainer>
      <Tab.Navigator 
        swipeEnabled={true}>
        <Tab.Screen name="A" component={AScreen} />
        <Tab.Screen name="B" component={BScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

function AScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text selectable={true}>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In non est eget elit pretium elementum. Praesent at metus elementum, auctor turpis ac, tristique ex. Praesent malesuada aliquam lacus, nec vestibulum lorem venenatis sed. Nullam tincidunt tristique massa, quis molestie metus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce arcu ex, pulvinar eu aliquet sed, facilisis et arcu. Proin sit amet mi est.</Text>
    </View>
  );
}

function BScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text selectable={true}>Sed leo lacus, bibendum cursus dignissim a, suscipit eget nisi. Aliquam vestibulum eros eget sem feugiat tincidunt placerat vel lorem. Pellentesque odio ligula, elementum ullamcorper urna at, cursus pharetra lectus. Aenean laoreet egestas sapien quis congue. Donec dictum, ex at congue faucibus, orci tortor pharetra libero, in laoreet velit enim eu velit. Aliquam porta nunc a lobortis facilisis. Curabitur tincidunt mollis nisl, scelerisque fermentum diam ultrices et. Phasellus eros sapien, mollis nec sodales at, sodales sit amet ante.</Text>
    </View>
  );
}

Steps To Reproduce

It’s easier to observe on a physical part because of the swipe action. In short, swipe from Tab A to Tab B by starting the swipe over the lorem ipsum text. Once the swipe is complete, swiping back from Tab B to Tab A without swiping over the text (i.e. starting the swipe either above or below the text) will show that text on Tab A had been selected.

I experienced this is my own project and was able to reproduce it with this very simple snack code below.

Expected behavior

When swiping between tabs, the swipe should occur without the text being selected, even if the swipe is initiated over the text.

Actual behavior

When using the Text component with the Text prop selectable={true} on screens under the Material Top Tab Navigator, swiping between the screens causes the text to be selected if the swipe is initiated over the text. This is undesirable, because no matter how fast the swipe is or how short in time the finger is touching the screen, the text is unintentionally highlighted/selected on swipe. The highlight seems to occur during/after the swipe is complete. I’ve provided sample code above wherein the problem arises.

Some things worth noting:

  • When changing the Tab.Navigator prop swipeEnabled to false and you try to swipe, the issue does not occur, so it appears that its the allowed swipe gesture that’s causing the issue.
  • I found an identical issue when scrolling vertically on screens (not on the tab navigator) that used Scrollview imported from ‘react-native-gesture-handler’. As soon as I imported the Scrollview from ‘react-native’ instead the issue went away. I know that ‘react-navigation’ makes use of ‘react-native-gesture-handler’ so maybe this issue is related to ‘react-native-gesture-handler’?

Snack or minimal code example

https://snack.expo.io/@cdlarson91/tab-swipe-selectable-bug

Package versions

  • React:16.13.1

  • React Native: 0.63.2

  • React Native Gesture Handler:1.7.0

  • react-native-screens: ~2.10.1

  • react-native-tab-view: ^2.0.0

  • react-native-reanimated: ~1.13.0

  • react-navigation/native: 5.9.2

  • react-native-safe-area-context: 3.1.4

  • react-native-community/masked-view: 0.1.10

  • react-navigation/material-top-tabs: 5.3.13

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
j-piaseckicommented, Mar 14, 2022

Hi! Could you try wrapping your selectable text views with NativeViewGestureHandler? I believe that it works correctly after this change:

import { NativeViewGestureHandler } from 'react-native-gesture-handler';
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";

const Tab = createMaterialTopTabNavigator();

export default function App() {
    return (
    <NavigationContainer>
      <Tab.Navigator 
        swipeEnabled={true}>
        <Tab.Screen name="A" component={AScreen} />
        <Tab.Screen name="B" component={BScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

function AScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <NativeViewGestureHandler>
        <Text selectable>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In non est eget elit pretium elementum. Praesent at metus elementum, auctor turpis ac, tristique ex. Praesent malesuada aliquam lacus, nec vestibulum lorem venenatis sed. Nullam tincidunt tristique massa, quis molestie metus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce arcu ex, pulvinar eu aliquet sed, facilisis et arcu. Proin sit amet mi est.</Text>
      </NativeViewGestureHandler>
    </View>
  );
}

function BScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <NativeViewGestureHandler>
        <Text selectable>Sed leo lacus, bibendum cursus dignissim a, suscipit eget nisi. Aliquam vestibulum eros eget sem feugiat tincidunt placerat vel lorem. Pellentesque odio ligula, elementum ullamcorper urna at, cursus pharetra lectus. Aenean laoreet egestas sapien quis congue. Donec dictum, ex at congue faucibus, orci tortor pharetra libero, in laoreet velit enim eu velit. Aliquam porta nunc a lobortis facilisis. Curabitur tincidunt mollis nisl, scelerisque fermentum diam ultrices et. Phasellus eros sapien, mollis nec sodales at, sodales sit amet ante.</Text>
      </NativeViewGestureHandler>
    </View>
  );
}
0reactions
j-piaseckicommented, Mar 14, 2022

Great! I will close this issue then. If you find any problems, please make a new one 😄.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unintended text selection when swiping between tabs #9337
I've provided sample code below wherein the problem arises. ... When swiping between tabs, the swipe should occur without the text being selected, ......
Read more >
Adjust how iPhone responds to your touch - Apple Support
If you tend to unintentionally shake iPhone, you can turn off Shake to Undo. Go to Settings > Accessibility > Touch. Tip: To...
Read more >
Tabs - Material Design
Users can navigate between tabs by tapping a tab, or by performing a swipe gesture over content. Navigate to a tab by tapping...
Read more >
Navigating between tabs in an android app
If your app uses action bar tabs, use swipe to navigate between the different views. ... They used tap instead of swipe to...
Read more >
Directives > mdTabs - AngularJS Material
If a tab is disabled while active/selected, then the next tab will be auto-selected. Theming. By default, tabs use your app's accent color...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found