How to use an horizontal scrollView while using createMaterialTopTabNavigator with swiping enabled, REACT NATIVE - react-native

i'm using createMaterialTopTabNavigator with a swipeEnabled set to True to navigate between screens, I have a Screen which contains an horizontal scrollView, the problems is that the scrollView isn't working, since whenever i try to scroll it horizontally the screen just changes to the next one.
I'd like to be able to disable the swipeEnabled when i swipe in the scrollView.
PS: i tried doing it dynamically by passing a variable to the Screen and a method that sets it to false using onTouchStart, but it's slower than the swiping event of the screen so it end up swiping to the next screen before onTouchStart event start.

Related

Using useRef to make a tap on a container ScrollView put focus in a TextInput

This is for a React Native app.
One of my screens has a ScrollView wrapped around a TextInput. The ScrollView has a lot of height - moreso than the TextInput when it's blank - so the behavior I want is that if a user taps on any of the 'blank space' in the ScrollView, it will put focus in the TextInput.
The code I have so far boils down to this:
export function MainInput() {
const ref_textinput = useRef();
const onTapScrollViewBody = () => {
console.log("Detected tap")
ref_textinput.current?.focus()
}
return (
<TouchableWithoutFeedback onPress={onTapScrollViewBody}>
<ScrollView style={styles.parentScrollView}>
<TextInput
ref={ref_textinput}
...
It's not working unfortunately. When focus isn't in the TextInput, the first time I tap in the blank space of the ScrollView, I do see the console log, but focus doesn't go into the TextInput, nor do further taps on the blank space trigger more console logs. However, tapping into the TextInput (which obviously puts focus back on it) then tapping back out will trigger the console log.
Am I misunderstanding how useRef works here?
Your understanding of useRef is fine, it's the understanding of the ScrollView that needs some help. If two elements that share coordinates are touchable, React Native will give the touch to the "top" element (whether by z-index, render order, etc). Your example creates the following hierarchy:
|-TouchableWithoutFeedback
|-ScrollView
|-TextInput
If you press within the TextInput's area, it will always capture the touch, as you found. If you press within the ScrollView's area, but outside of the text input, your touch is captured by the ScrollView, which will try to use your touch to scroll it. Only when you touch outside the ScrollView should your TouchableWithoutFeedback activate.
You still want the ScrollView to scroll, so when do you want your tap to focus the text input? You could delete your Touchable and use an event exposed by ScrollView, like
<ScrollView
onScrollEndDrag={() => ref_textinput.current?.focus()}
// and/or
onMomentumScrollEnd={() => ref_textinput.current?.focus()}
...
A solution that would handle tapping differently from scrolling could be achieved using react-native-gesture-handler, but it would be more involved.

react-native ScrollView display an absolute item outside of the ScrollView

Hi I have tooltip buttons in my TextInput when user press open a tooltip and I'm taking TextInput values from an array because of that I'm using ScrollView or FlatList.
My problem is that the tooltip of the TOP TextInput is not all visible. As you see in the below tooltip of StoreKey stays outside of ScrollView(PINK).
Is there any way to show it outside of the ScrollView ?
Note: I can use also FlatList.

Swipeable area in react-native-swiper

Is there any way we can set the swipe able area in react-native-swiper? For example, from the mock screen, I would like the screen to be swiped only when the user swipe on the area marked by black border.
PS: The default behaviour is to let the screen swipe from any where in the swiper component.
Mock Screen

ScrollView only scrolls when placing finger inside of an input

I'm having a weird behavior here and I can't figure out what's going on. I have a ScrolView with a form and some inputs and labels inside and it seems to only want to scroll when you place your finger (or cursor in the demo) over an input or a switch and it doesn't scroll when placing your finger anywhere else in the ScrollView
I put together an Expo Snack to show the code and if you run in the emulator and attempt to scroll the ScrollView by placing the cursor over one of the labels or on the edges of the ScrollView it won't scroll but if you place the cursor over an input or a switch it scrolls just fine
https://snack.expo.io/#jordanr/weird-scrollview-bahavior
The issue is because Touchable effects in your TouchableWithoutFeedback are blocking the effects of ScrollView, therefore you need to reset your responder by wrapping the Content inside the View
<Content>
<View onStartShouldSetResponder={() => true}>
//... Rest of the code
</View>
</Content>
Also don't use ScrollView since NativeBase uses KeyboardAwareScrollView from the package react-native-keyboard-aware-scroll-view in the <Content/>

Ignore rest of screen when keyboard active

So i am adding the final touches to my application, and one bug that has been present for a while is when they keyboard is active, i am able to use the navigation on the upper half of the screen with the keyboard still showing
Is there a simple way to dismiss all other touches on the upper half of the screen when the keyboard is active? If you could point me in the right direction that would be great.
Looking for something similar to this: When keyboard active then touch screen anywhere, close keyboard
EDIT: would be nice if the textInput that the keyboard is outputting to was still touchable
If the parent view of the TextInput is a ScrollView, then u can use the prop 'keyboardShouldPersistTaps',
<ScrollView keyboardShouldPersistTaps='handled' />
If you're using a View and dont want scrolling, then probably u can wrap it inside a
//This should disable scroll
<ScrollView scrollEnabled={false} >
Documentation for keyboardShouldPersistTaps (React Native website)
keyboardShouldPersistTaps?: enum('always', 'never', 'handled', false,
true) #
Determines when the keyboard should stay visible after a tap.
'never' (the default), tapping outside of the focused text input when
the keyboard is up dismisses the keyboard. When this happens, children
won't receive the tap. 'always', the keyboard will not dismiss
automatically, and the scroll view will not catch taps, but children
of the scroll view can catch taps. 'handled', the keyboard will not
dismiss automatically when the tap was handled by a children, (or
captured by an ancestor). false, deprecated, use 'never' instead true,
deprecated, use 'always' instead