In React Native, how can I get ScrollView and InputAccessoryView to avoid the keyboard? - react-native

I'm trying to create an iMessage like sticky text input where the ScrollView content moves up when the keyboard is shown and down when the keyboard is dragged closed. In the React Native repository on Github, there is an example InputAccessoryViewExample.js that is almost exactly what I want, except when the keyboard is shown, ScrollView's content (the messages) are covered by the keyboard.
I've tried a few permutations of the following with no success.
<>
<KeyboardAvoidingView style={{flex: 1}} behavior="padding">
<ScrollView style={{flex: 1}} keyboardDismissMode="interactive">
{Array(15)
.fill()
.map((_, i) => <Message key={i} />)}
</ScrollView>
</KeyboardAvoidingView>
<InputAccessoryView backgroundColor="#fffffff7">
<TextInputBar />
</InputAccessoryView>
</>

Related

React native touchable not working with keyboard

I am using bare react-native CLI.
My modal has a text input field inside. In the modal, when I open the keyboard, the buttons next to the text input are not working. They close the keyboard when tapped instead of working.
I tried it using the native modal module (with KeyboardAvoidingView) and using the react-native-modal
Image
// with react-native-modal
<View style={styles.PostCommentArea}>
<View style={styles.PostBody}>
<Image
source={{ uri: UserDetails.profile_image }}
style={styles.UserImg}
/>
<InputField
ref={InputRef}
style={styles.InputField}
length={0.65}
hv={0.055}
placeholder="Add Comment..."
onSubmitEditing={postComment}
/>
<TouchableHighlight style={styles.PostBtn} onPress={postComment}>
{PostingComment ? (
<>
<Indicator size="small" color={Colors.WHITE} />
</>
) : (
<IconOutline
name="arrow-up"
size={height * 0.027}
color={Colors.WHITE}
/>
)}
</TouchableHighlight>
</View>
</View>
One way of fixing this is wrapping the component in a ScrollView and using the keyboardShouldPersistTaps prop.
'never' 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 children of the scroll view (or captured
by an ancestor).
<ScrollView keyboardShouldPersistTaps={'handled'}>
...
</ScrollView>

React Native: Fix TextInput at the bottom of the screen with a ScrollView

I need to fix the input in the bottom of the screen, so that keyboard pushes this input (similar to instagram comments).
Here's an example():
https://snack.expo.io/LPRwoGpik
It's working fine, but if I put the FlatList inside the ScrollView the bottom input is dissapearing.
What's the right way to solve this problem?
try this
<View style={{flex: 1,}} >
<ScrollView>
{content}
</ScrollView>
<TextInput style={{position: "absolute", bottom :0}}/>
</View>

React Native onLongPress triggered onPress if pressed component is re-rendered

I am implementing an image gallery. There's a list of squared images, if user longPress an image component it will re-render to a selected image component which show a blur background and a tick on top of the image.
Here's the normal image component:
<TouchableOpacity
key={index}
onPress={this.normalModeImgClick(img, index)}
onLongPress={this.startSelectMode(index)}
>
<Image style={styles.img} source={{uri: img.resized_xs_url}}/>
</TouchableOpacity>
Here's the component at select mode:
<TouchableOpacity
key={itemIndex}
style={styles.selectedImgWrapper}
onPress={this.selectModeImgClick(imgItem, itemIndex)}
>
<Image style={styles.img} source={{uri: imgItem.img.resized_xs_url}}/>
{imgItem.selected &&
<View style={styles.selectedImgCover}>
<Image style={styles.selectedIcon} source={require('../../assets/icon_tick.png')}/>
</View>
}
</TouchableOpacity>
As you can see, if you longPress a normal image component startSelectMode will trigger, and that image will re-render and turned to a select mode component. However, selectModeImgClick will also be triggered which it is not supposed to (as the user is still doing the longPress action).
How to prevent this happening?
Accidentally discovered an alternative right after I posted the question, solved by adding an empty onLongPress function props to the selected mode component like this:
<TouchableOpacity
key={itemIndex}
style={styles.selectedImgWrapper}
onPress={this.selectModeImgClick(imgItem, itemIndex)}
// Override 'onLongPress' with an empty function
onLongPress={() => {}}
>
<Image style={styles.img} source={{uri: imgItem.img.resized_xs_url}}/>
{imgItem.selected &&
<View style={styles.selectedImgCover}>
<Image style={styles.selectedIcon} source={require('../../assets/icon_tick.png')}/>
</View>
}
</TouchableOpacity>
Since the component is not designed to have a longPress action, I'm looking forward to better solutions:

How to create swipeable bottom sheet in React Native?

How to implement exactly the same swipeable bottom sheet in React Native:
react-swipeable-bottom-sheet (demo gif above) lib is working only in React.
I know react-native-overlay-section but it is opening to the top of the window with bounce animation.
EDIT
I also tried react-native-touch-through-view, but there is a known issue with touches through the TouchThroughView...
<View style={styles.container}>
<View style={styles.contentContainer}>
<FlatList
data={this.state.list}
renderItem={(data) => {
<View>
<Text>{"Bla bla bla"}</Text>
<TouchableOpacity onPress={()=> this.onPress()}>
<Text>{"THIS IS NOT WORKING ON ANDROID"}</Text>
</TouchableOpacity>
</View>
}} />
</View>
<TouchThroughWrapper style={styles.scrollWrapper}>
<ListView
style={styles.scroller}
dataSource={actionsList}
renderHeader={() => <TouchThroughView style={styles.touchThroughView} />}
renderRow={(rowData) => {
return (
<Text style={styles.itemRow}>{rowData}</Text>
)
}}>
</ListView>
</TouchThroughWrapper>
You can achieve your requirement with the help of following package.
https://www.npmjs.com/package/react-native-touch-through-view
This package allows scroll views and table views to scroll over interactable content without poor performing size and bounds animations.

React Native detect tap on View

I’m writing a React Native app and I want to detect tap/clicks anywhere on the screen so I put an onClick handler on my <View> element but it doesn’t seem to be working. Here is my render function:
<View style={styles.container} onClick={this.onClick}>
<Text style={styles.welcome}>
Tap to change the background
</Text>
</View>
What do I need to do?
For making any element to handle touch/click events in a React-Native UI, you need to put the element inside a TouchableOpacity, TouchableWithoutFeedback, TouchableNativeFeedback or TouchableHighlight element:
<TouchableHighlight onPress = { this.onClick }>
<View style={styles.container}>
<Text style={styles.welcome}>
Tap to change the background
</Text>
</View>
</TouchableHighlight>
Hope that helps.
In React Native version > 55.3 you make check onPress events into your View if use onStartShouldSetResponder props.
Like example:
<View
style={{ flex: 1 }}
onStartShouldSetResponder={() => console.log('You click by View')}
>
<ScrollView
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this.onRefresh} />
}
>
<Text>Awesome</Text>
</ScrollView>
</View>
In example I showed how you can get onPress event on View and not blocking other event behind them. Refresh control still work correct.
In my case the following works fine. You can use onTouchStart and onTouchEnd handlers on any View via props, for example:
<View onTouchStart={() => this.doSomething()} />
More information
This worked for me...
onTouchEnd={() => alert('TAPPED')}
The easiest way to do that:
<TouchableOpacity style={styles.container} onPress={()=> whateverFunc(parameter)}>
<Text style={styles.welcome}>
Tap to change the background
</Text>
</TouchableOpacity>
So, you need to replace the 'View' component to a 'TouchableOpacity' or any other Touchable component and you also need to replace the 'onClick' prop to 'onPress'. That's all. The wrapping of a view with a TouchableWhatever component is not necessary at all.