Keyboard blocking textinput with Scrollview and KeyboardAvoidingView in react native - javascript

I am using RN 0.55.4 + Expo
I tried to use KeyboardAvoidingView to my form but it doesnt change anything with or without KeyboardAvoidingView, its still blocking my form. I am using
tcomb-form
This is my current code
return (
<View style={styles.container}>
<KeyboardAvoidingView>
<ScrollView>
<View>
<Header/>
<View style={styles.inputs}>
<LoginForm
formType={formType}
form={this.props.auth.form}
value={this.state.value}
onChange={self.onChange.bind(self)}/>
{passwordCheckbox}
</View>
<FormButton/>
<View >
<View style={styles.forgotContainer}>
{leftMessage}
{rightMessage}
</View>
</View>
</View>
</ScrollView>
</KeyboardAvoidingView>
</View>
)
This is the style
var styles = StyleSheet.create({
container: {
flexDirection: 'column',
flex: 1
},
inputs: {
marginTop: 10,
marginBottom: 10,
marginLeft: 10,
marginRight: 10
},
forgotContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 10,
marginLeft: 10,
marginRight: 10
}
})
This is the display
I also tried https://github.com/APSL/react-native-keyboard-aware-scroll-view library but still same result, keyboard is blocking the view / form.
Anyone know whats wrong?

For iOS you should set the "behavior" parameter of the KeyboardAvoidingView to "padding" :
<KeyboardAvoidingView behavior="padding">
Refering to react-native documentation :
Note: Android and iOS both interact with this prop differently.
Android may behave better when given no behavior prop at all, whereas
iOS is the opposite.
A working example on iOS and Android :
<KeyboardAvoidingView behavior={Platform.OS == "ios" ? "padding" : null}>

It also happened to me... ScrollView and FlatList can work it out by setting a dynamic height depending on your data to FlatList. eg:
<ScrollView>
<FlatList style={{height: dataArr.length * YourInputHeight}}
...
/>
</ScrollView>

Related

ScrollView not working in react-native app, content disappears when attempting to add flex and flexGrow

for some reason a ScrollView in one of my components isn't working despite working in every other component I've implemented it in. Attempting to implement solutions to similar problems seems to just make the content I want displayed disappear.
I'm expecting to have a scrollable list of sample restaurant dishes. I created some dummy data to pass in for now but noticed it didn't scroll after reaching the end of the phone screen.
const testFoods = [
{
title: "test",
description: "Lorem Ipsum",
price: "$7.77",
image: "dummyLink",
},
// Same as above but 4 more times, didn't want to clog up the description
];
export default function MenuItems() {
return (
<ScrollView showsVerticalScrollIndicator={false}>
{testFoods.map((food, index) => (
<View key={index}>
<View style={styles.menuItemStyle}>
<FoodDetails food={food} />
<FoodImage food={food} />
</View>
</View>
))}
</ScrollView>
);
}
const FoodDetails = (props) => (
<View style={{ width: 240, justifyContent: "space-evenly" }}>
<Text style={styles.titleStyle}>{props.food.title}</Text>
<Text>{props.food.description}</Text>
<Text>{props.food.price}</Text>
</View>
);
const FoodImage = (props) => (
<View>
<Image
source={{ uri: props.food.image }}
style={{
width: 100,
height: 100,
borderRadius: 8,
}}
/>
</View>
);
const styles = StyleSheet.create({
menuItemStyle: {
flexDirection: "row",
justifyContent: "space-between",
margin: 20,
},
titleStyle: {
fontSize: 19,
fontWeight: "600",
},
});
The result is like so
Result with code above
The Header component with the sample restaurant image is a separate component by the way.
I have more data that can't be seen as for whatever reason the screen refuses to scroll. I'm using my actual phone for the tests but the result is the same when I use an emulator, scrolling doesn't work. After looking online I thought I would try adding a parent View with flex: 1 and a flexGrow: 1 to contentContainerStyle inside the ScrollView like so.
export default function MenuItems() {
return (
<View style={{ flex: 1 }}>
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{ flexGrow: 1 }}
>
{testFoods.map((food, index) => (
<View key={index} style={styles.menuItemStyle}>
<FoodDetails food={food} />
<FoodImage food={food} />
</View>
))}
</ScrollView>
</View>
);
}
But that only resulted in the content disappearing. Reloading the app didn't change anything either Result after trying above code
Attempting to use a FlatList had the same result. I've also read that having percentage based styling values on height for any of the children components can make the scrolling stop working but all my components don't utilize such. Oddly enough when I change the styling on the outer view to height: 400, I'm able to get the scrolling to work but this is very sloppy and will likely only work on phone screens similar to mine. I know the ScrollView component is working fine, as when I add "horizontal" to it the scrolling works just fine and I'm able to scroll to the last item in the dataset. Obviously all the content is horizontal now though. After adding horizontal too ScrollView, scrolling works fine horizontally
Any ideas? Could it be some part of my styling I'm not noticing? I'm unable to test this on IOS so I'm not sure if it's an Android specific problem, would be strange though as scrolling worked fine in my other components.
Here's also the Header component code just in case it could be anything in there, although It shouldn't be.
const testImage =
"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Restaurant_N%C3%A4sinneula.jpg/800px-Restaurant_N%C3%A4sinneula.jpg";
const testTitle = "Sample Restaurant";
const testDescription = "Thai · Comfort · $$ · 🎫 · 4 ⭐ (217+)";
export default function About() {
return (
<View>
<RestaurantImage image={testImage} />
<RestaurantTitle title={testTitle} />
<RestaurantDescription description={testDescription} />
</View>
);
}
const RestaurantImage = (props) => (
<Image source={{ uri: props.image }} style={{ width: "100%", height: 180 }} />
);
const RestaurantTitle = (props) => (
<Text
style={{
fontSize: 29,
fontWeight: "600",
marginTop: 10,
marginHorizontal: 15,
}}
>
{props.title}
</Text>
);
const RestaurantDescription = (props) => (
<Text
style={{
marginTop: 10,
marginHorizontal: 15,
fontWeight: "400",
fontSize: 15.5,
}}
>
{props.description}
</Text>
);
Wrap your card with TouchableOpacity.
<TouchableOpacity activeOpacity={0} key={index} style={styles.menuItemStyle}>
<FoodDetails food={food} />
<FoodImage food={food} />
</TouchableOpacity>
I hope this thing will work.

IOS expo-camera preview remains black screen

Expected Behavior : In IOS StandAlone app making expo-camera preview not black screen.
Some things to add: I have in app.json the infoPlist the NSCameraUsageDescription-
I ask the user to allow the use of camera, when this pops the screen is blank and when he accepts the preview remains black
When testing this on Dev ( expo app ) it works perfectly
When testing on expo build and open the app on expo app it works too
when i eas build and sent do app store connect , in testflight or in standalone app it doesnt work!
expo-camera version : "expo-camera": "~12.2.0",
Example
return (
{previewVisible && capturedImage ? (
) : (
<Camera style={styles.camera}
type={type}
ref={camera}
flashMode={'auto'}
whiteBalance={"sunny"}
>
<View style={{ flex: 1, flexDirection: 'column', justifyContent: 'flex-end' }} >
<LinearGradient style={[{ padding: 15, elevation: 10, paddingBottom: 25 }]} colors={['transparent', 'black']}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }} >
<TouchableOpacity onPress={voltarEcraAnterior} style={[styles.previewButtons, styles.circle]}>
<Icon name="icon-cross" style={styles.iconButtonsCamera} size={40}></Icon>
</TouchableOpacity>
<TouchableOpacity onPress={takePicture} style={[styles.previewButtons, styles.circle,]}>
<Icon name="icon-scan" style={styles.iconButtonsCamera} size={40}></Icon>
</TouchableOpacity>
</View>
</LinearGradient>
</View>
</Camera>
)
}
</View >
);
Permissions
const __startCamera = async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === 'granted');
}

React Native: Scrollview won't scroll with row direction and flexWrap

in my react-native app I have a scrollview where my list items are row wrapped (flexDirection:'row',flexWrap:'wrap'), however because of this my scrollview won't scroll for some reason...
My scrollview:
<View style={{flex:1}}>
<ScrollView vertical={true} contentContainerStyle={{ borderWidth:1,flex:1,flexDirection:'row',flexWrap:'wrap',alignItems: 'flex-start'}}>
{root.userStore.passionOptions.map((item,index) => {return (
<Text key={item} onPress={ ()=>{ Alert.alert('kaka') } } style={{ fontSize:18,padding:5,paddingLeft:10,paddingRight:10,color:'rgb(125,125,125)',borderRadius:35,borderWidth:1,borderColor:'rgba(0,0,0,0.1)',margin:5 }}>{item}</Text>
)
})}
</ScrollView>
</View>
EDIT:I tried removing flexWrap and flexDirection property and it won't scroll neither
It works for me like this i made the scrollView the outter component
<ScrollView>
<View
lightColor="#eee"
style={{ paddingHorizontal: 7, paddingVertical: 5 }}
>
{children}
</View>
</ScrollView>
Reason not to work:
Your flexDirection is conflicting with ScrollDirection.
Solution:
So to avoid conflict you can have another View inside ScrollView and do the flexWrap logic
<ScrollView>
<View
style={{
borderWidth:1,
flex:1,
flexDirection:'row',
flexWrap:'wrap',
alignItems: 'flex-start'
}}
>
...Your Views over here...
</View>
</ScrollView>

React Native ImageBackground in FlatList header

I am testing my app on android and I have seen that when I scroll down and then to the top of my flatlist, the header (which have an ImageBackground component) is blank (it seems that dissapears when it is not visible in the screen) and then fades in. I don't have this error on iOS, only in android.
Here is the code of the FlatList:
<FlatList
ref={scrollRef}
refreshControl={
<RefreshControl
refreshing={isRefreshing}
colors={[
colors.primary,
colors.pink,
colors.strawberry,
colors.pig,
]}
tintColor={colors.primary}
onRefresh={handleRefresh}
/>
}
ListHeaderComponent={
<View style={styles.headerContainer}>
<Header
uploadProgress={uploadProgress}
onConfigurationButtonPress={handleConfigurationDisplay}
/>
</View>
}
ListFooterComponent={<Tab />}
style={[styles.container, { backgroundColor: colors.white }]}
/>
As you can see, in my flatlist I have two components, a tab in the footer, and a custom component called Header, which code is:
...
<ImageBackground
source={{ uri }}
blurRadius={Platform.OS === "ios" ? 40 : 10}
style={styles.container}
>
<View
style={[styles.overlay, { backgroundColor: colors.transparentWhite }]}
/>
{children}
</ImageBackground>
...
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
},
overlay: {
...StyleSheet.absoluteFillObject,
},
});
Any ideas? Thanks.

KeyboardAvoidingView "Padding" not working properly

I got a problem with KeyboardAvoidingView I have 3 TextInput and when I want to write something on the last one this one is steal hidden by my keyboard.
export default class App extends React.Component {
render() {
return (
<LinearGradient colors={['#72afd3', '#37ecba']} style={styles.container}>
<KeyboardAvoidingView behavior='padding' enabled>
<TextInput placeholder='Hello World'/>
<View style={{height: 200}}/>
<TextInput placeholder='Hello World'/>
<View style={{height: 200}}/>
<TextInput placeholder='Hello World'/>
</KeyboardAvoidingView>
</LinearGradient>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
})
Use keyboardVerticalOffset so that the textInput won't be hidden behind the keyboard
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={(Platform.OS === 'ios') ? "padding" : null} enabled
keyboardVerticalOffset={Platform.select({ios: 80, android: 500})}>
And to anyone who is having trouble with a position:'absolute' View
keep being pushed by the keyboard, put the View inside
KeyboardAvoidingView
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={(Platform.OS === 'ios') ? "padding" : null} enabled>
//content here
<Button title="Login" style={{position:'absolute', bottom:20}}/>
</KeyboardAvoidingView>
I am using react-native-keyboard-aware-scroll-view.
This will probably work:
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
<KeyboardAwareScrollView enableOnAndroid extraScrollHeight={pixels[50]}>
<LinearGradient colors={['#72afd3', '#37ecba']} style={styles.container}>
<TextInput placeholder='Hello World'/>
<View style={{height: 200}}/>
<TextInput placeholder='Hello World'/>
<View style={{height: 200}}/>
<TextInput placeholder='Hello World'/>
</LinearGradient>
</KeyboardAwareScrollView>
Usually, on Android, your desired result will be better with no behavior prop given. Whereas on iOS padding may be the right answer. See note on https://facebook.github.io/react-native/docs/keyboardavoidingview#behavior
I usually write something like this:
<KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : undefined}>
// ...
</KeyboardAvoidingView>
I used #Emma's answer but fixed offsets with keyboardVerticalOffset. I used below one.
<KeyboardAvoidingView
style={styles.keyboardAvoidContainer}
enabled
behavior={"padding"} // you can change that by using Platform
keyboardVerticalOffset={Platform.select({ ios: 60, android: 78 })}
>
I give 60 to VerticalOffset of ios and tested because fully fitted to several of simulators which is contains iPhone X, iPhone 8 and iPhone 6. Then in Android Nexus Emulator, it's fitted with value of 78.

Categories

Resources