In my app keyboard covers only bottom part of the text input. I have tried several ways to solve this by changing styles by adding padding or margin, and also KeyboardAvoidingView didn't help.
Another problem is that keyboard shifts the whole screen and header becomes invisible as it goes above.
Edit: It works fine on IOS devices.
How can I fix these problems?
Thanks
Code:
<>
<CustomHeader title={item.title}
leftChild={<SvgImageComp name={MENU_ICON}/>}
centerChild={
<TextComp text={'Title'} style={compStyle.title}/>
}
/>
<View style={{
flex: 1,
justifyContent: 'flex-end'
}}>
<KeyboardAvoidingView
behavior={"height"}
>
<TextInputComp fontFamily={NUNITO_SANS_REGULAR}
fontSize={15}
lineHeight={20}
autoFocus={true}
style={{
paddingVertical: 10,
paddingHorizontal: 20,
borderWidth: 1,
borderColor: '#000',
borderRadius: 200,
}}
/>
</KeyboardAvoidingView>
</View>
</>
For Android you don't need to pass behavior to KeyboardAvoidingView. For IOS you need to pass behavior="position" and keyboardVerticalOffset=[height of your input].
<KeyboardAvoidingView
{...(Platform.OS === 'ios'
? {
behavior: 'position' ,
keyboardVerticalOffset: [inputHeight], // calculate height using onLayout callback method
}
: {})}>
I avoid this issue by wrapping the screen in <ScrollView contentContainerStyle={flexGrow: 1}><ScrollView> This will make the whole screen turn into a scroll view once the keyboard opens. Allowing the box to be out of the way of the keyboard. This also has the added benefit of allowing you to scroll to other sections of the screen for reference while the keyboard stays open.
Related
I need some help. So scenario is that I am using ScrollView component in react native whose props have horizontal for horizontal scrolling. And I have two button whose purpose is to control to scroll to next card and previous card. Now I want to disable swipe gesture only for ScrollView. User should/could not scroll content with swipe gesture but they can only scroll with help of button only. As I try using ScrollView's available props as well which is scrollEnabled={false}. But It will helps me to stop swipe gesture but also button controller to scroll is stop working. Here is my method for button controller.
const scrollToNextInfo = () => {
if (scrollViewRef) {
scrollViewRef?.current?.scrollTo({
x: selectScreenWidth + widthOfCard,
y: 0,
animated: true,
});
}
};
And ScrollView Component Looks as:
<ScrollView
ref={scrollViewRef}
horizontal
pagingEnabled
// scrollEnabled={false}
showsHorizontalScrollIndicator={false}
>
// Card Component with width as widthOfCard
</ScrollView>
{/** Button Controller Component **/}
<View
style={{
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}>
<TouchableOpacity
style={styles.previousButton}
onPress={scrollToNextInfo}
>
<LeftIcon />
</TouchableOpacity>
</View>
Hoping for positive response. Thank you in advance. :)
When I tried just to render the HomeScreen component not using Stack.Screen I was able to get 100% width but when I tried to use code bellow, 100% width screen is not working
const HomeScreen = () => {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'red'}}>
<Text>Home Screen</Text>
</View>
);
}
const MainContainer = () => {
return (
<NavigationContainer >
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
Not only that, the width is zero if you set headerShown: false.
Just remove the outer View of the NavigationContainer. It works for me.
Can you try with display: flex and remove flex:1
Were you running the remote debugger when you were having this issue? I had the same problem and it resolved when I turned it off.
It seems like it might be a slow load issue and the stylesheets aren't being applied before rendering, so the screen is taking the width of the header text (I may be completely wrong about this though). When I removed the style prop from my View component, saved it, then put it back and saved again it temporarily resolved the issue until I reloaded Expo.
I'm developing project on react-native, my problem is that modal is over the drawer navigator, I tried set zIndex but it is useless.
My modal:
<Modal visible={isVisible} animationType={'fade'} transparent={true}>
<Animated.View style={{ marginTop: marginTop, zIndex: 0 }}>
...
</Animated.View>
</Modal>
My drawer:
<DrawerContentScrollView {...props} style={{ marginTop: -5 }}>
<ImageBackground source={back} style={{...s.drawerContainer, zIndex: 100}}>
...
</ImageBackground>
</DrawerContentScrollView>
here is screenshot, I need to set drawer over this modal
The modal is natively on top of everything, check this question as well: Bring View on top of Modal using zIndex style with React-Native
You cannot put the drawer above it unfortunately.
I am trying to center a text input with a width that is the length of the text input. However when I use alignSelf: 'center', or alignItems: 'center', the text input is not visible without a width.
For example:
render() {
return <View style={{flex: 1}}>
<TextInput style={{alignSelf: 'center', minWidth: 1}}>
<View/>
}
Here the minWidth ensures that the textInput can be seen but it does not expand when you type in it. And without a width / minWidth the textInput would not be seen unless the centering style was removed.
Example with almost workable workaround:
constructor(props) {
super(props)
this.state = {
txt: ""
txtWidth: 0
}
}
render() {
return <View style={{flex: 1}}>
<TextInput
style={{minWidth: 1, alignSelf: 'center', width: this.state.txtWidth}}
value={this.state.txt}
onChange={txt=>this.setState({txt: txt.nativeEvent.text})}
/>
<Text
style={{position: 'absolute', right: 100000}}
onLayout={e=>this.setState({txtWidth:e.nativeEvent.layout.width})}
>
{this.state.txt}
</Text>
<View/>
}
As the text input receives input, it grows in size and works great. However, one thing prevents it from being full proof. The e.nativeEvent.layout.width value for emoji is always 20. And the actual width of the given emoji is not 20. Thus the txtWidth is no longer the correct width for the textInput and pieces of the textInput are now cut off.
Has anyone come up with a good solution for a centered text input with a dynamic width. I have been stumped on this for way too long. Would be happy to provide clarity if needed as well.
Thanks!
Sorry kept you waiting, fininally got time to finish this. Use View,Image and Text to fake TextInput.
1st step: format text when changed
you still need a TextInput.
emoji in text might look like :fire: or 🔥, I choose the later.
when text changes use regexp replace all emoji expressions to emoji character.
then you move cursor it will not stop inside an emoji
2nd setp: faked TextInput
it should look like
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
<Image style={styles.img} source={{uri: some_emoji}} />
<Text>
{"s"}
</Text>
<Text>
{"s"}
</Text>
<MyCursor />
</View>
the emoji images should be within the same width, and to get width of Text might look like
<Text onLayout={(event) => {
var {x, y, width, height} = event.nativeEvent.layout;
}} />
then you can get the total length and resize your View and hide your real TextInput and manage cursor, It worked in the web though not that smooth.
this is why i use Text for every char like <Text>{"s"}</Text> cursor index should change when you click on each of them, and when focus, blur and keypress happens. you may refer https://github.com/postor/react-input-emoji/blob/master/pages/index.js for a web version fake input I've tried, yet cut, paste and lot's of things remain unhandled
I use the keyboardAvoidingView, to display inputs and used next focus. But, when i click in first input ( print label 1623 - Acidez ), this is hidden. How make show this?
<ReactNative.View key={this.state.selectedTabIndex}>
<ReactNative.ScrollView style={{ height: this.props.styles.height - 40 }}>
<ReactNative.KeyboardAvoidingView
keyboardVerticalOffset={0}
behavior="position"
contentContainerStyle={{ paddingTop: this.state.size }}
>
{this.tabs[this.state.selectedTabIndex].render()}
</ReactNative.KeyboardAvoidingView>
</ReactNative.ScrollView>
</ReactNative.View>
if you increase 'keyboardVerticalOffset' to bigger value like '100' of KeyboardAvoidingView to some bigger amount it would scroll up from keyboard thus avoiding it.I also spent much time in finding the right solution on internet but finally figure it out myself for 'react-native' version '0.50.4'.I got it working like this
<View style={…..}>
<ScrollView>
<KeyboardAvoidingView style={{ flex: 1 }}
keyboardVerticalOffset={100} behavior={"position"}>
</KeyboardAvoidingView>
</ScrollView>
</View>
keyboardVerticalOffset should be the distance between the top of the screen and the top of the KeyboardAvoidingView. If you're using flex, that number is going to be different depending on the size of the device you're viewing the app on.
The simplest approach I have found is to simply wrap the whole page with KeyboardAvoidingView. By making it your top-level wrapper, you will never have to worry about the keyboardVerticalOffset.
Experiment with the three behavior options from there until you get something that works.
What works today for me - on android - was..
<KeyboardAvoidingView
key={2}
keyboardVerticalOffset={0}
behavior={"padding"}
style={{
flex: 1,
overflow: "hidden",
height: "100%",
paddingTop: 0,
marginTop: 0,
borderTopWidth: 0,
}}
windowSize={1}
enabled
>
(...)
</KeyboardAvoidingView>