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');
}
Related
The code below shows how all the functions are implemented
On iOS everything works fine, the button changes slide, the dots on the bottom change state based on the page and on the last page it displays a signup button,
On Android, the button works only on the first page, the last page doesnt show the signup button, and next button doesnt work on the second page!
export default function introScreen({ navigation }) {
const [sliderState, setSliderState] = useState({ currentPage: 0 });
const scrollRef = useRef();
const { width, height } = Dimensions.get('window')
const notchSize = StatusBar.currentHeight
const setSliderPage = (event: any) => {
const { currentPage } = sliderState;
const { x } = event.nativeEvent.contentOffset;
const indexOfNextScreen = Math.floor(x / width);
if (indexOfNextScreen !== currentPage) {
setSliderState({
...sliderState,
currentPage: indexOfNextScreen,
});
}
};
const { currentPage: pageIndex } = sliderState;
const onPressTouch = () => {
scrollRef.current?.scrollTo({
x: width*(pageIndex+1),
animated: true,
});
}
return (
<>
<StatusBar hidden />
<SafeAreaView style={{ flex: 1, backgroundColor:'black' }}>
<ScrollView
style={{ flex: 1 }}
horizontal={true}
scrollEventThrottle={16}
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
onScroll={(event: any) => {
setSliderPage(event);
}}
ref={scrollRef}
>
<View style={{ width, height, alignItems: 'center', }}>
<Image source={require('../../assets/images/Intorduction/1.png')} style={styles.imageStyle} />
<BlurView tint={'dark'} intensity={70} style={{width:'80%',borderRadius:10, marginTop:10}}>
<Text style={[styles.textStyle,{color:'rgb(255, 190, 46)'}]}bla bla</Text>
</BlurView>
</View>
<View style={{ width, height, alignItems: 'center' }}>
<Image source={require('../../assets/images/Intorduction/2.png')} style={styles.imageStyle} />
<BlurView tint={'dark'} intensity={70} style={{width:'80%',borderRadius:10, marginTop:10}}>
<Text style={[styles.textStyle,{color:'rgb(255, 190, 46)'}]}>bla bla</Text>
</BlurView>
</View>
<View style={{ width, height, alignItems: 'center' }}>
<Image source={require('../../assets/images/Intorduction/3.png')} style={styles.imageStyle} />
<BlurView tint={'light'} intensity={70} style={{width:'80%',borderRadius:10, marginTop:10}}>
<Text style={[styles.textStyle,{color:'rgb(241, 250, 238)'}]}>bla bla</Text>
</BlurView>
</View>
</ScrollView>
{pageIndex != 2 ?
<View style={styles.paginationWrapper}>
{Array.from(Array(3).keys()).map((key, index) => (
<View style={[styles.paginationDots, { opacity: pageIndex === index ? 1 : 0.2 }]} key={index} />
))}
</View>
:
<></>
}
{pageIndex != 2 ?
<BlurView tint={'dark'} intensity={70} style={styles.nextButton}>
<TouchableOpacity style={{flex:1, justifyContent:'center', alignItems:'center'}} onPress={onPressTouch} >
<Text style={{color:'rgb(241, 250, 238)',fontFamily: 'poiret-one', fontSize:25}}>
Next
</Text>
</TouchableOpacity>
</BlurView>
:
<BlurView tint={'light'} intensity={70} style={styles.signUpButton}>
<TouchableOpacity style={{flex:1, justifyContent:'center', alignItems:'center'}} onPress={() =>navigation.navigate('Login')} >
<Text style={{color:'black',fontFamily: 'poiret-one', fontSize:25}}>
Sign Up
</Text>
</TouchableOpacity>
</BlurView>
}
</SafeAreaView>
</>
);
}
I have narrowed down the problem to the width and the 'event.nativeEvent.contentOffset', the returning number is close to 1 but it is (0.9), therefor math.floor was giving 0 as the index number,
I have changed Math.floor to Math.round and it is working perfectly fine,
If anyone wants a Introduction Slider for their app they can use this
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.
I have been building this react native app and it has run flawlessly on all simulators, both in debug and release mode.
However, as i started testing on devices, only android 7.0 devices experience inconsistent crashes with the app. It does not just crash on startup, sometimes it waits for the images to load before it crashes. Sometimes when i type in a textfield (during login) it crashes.
The biggest issue here is that there are no errors thrown during debug.
I have tried running
adb logcat *:S ReactNative:V ReactNativeJS:V
but no errors are thrown there.
Using
adb logcat *:E
the only error i get is this:
render function of component that contains everything:
render() {
if(!this.state.merchants || this.state.merchants.length == 0)
{
return <View style={{flex: 1,width: '100%', justifyContent:'center', alignItems: 'center', backgroundColor: Colors.themeBackground}}>
<Text style={{fontFamily: 'avenir-medium', width:'60%', color: 'gray', fontSize: 26, textAlign: 'center'}}>
Connection Error. Please check your connection and refresh!
</Text>
</View>
}
return (
<View style={{ backgroundColor: Colors.themeBackground, flex: 1 }}>
<FlatList
data={this.state.merchants}
extraData={this.state.refresh}
renderItem={({ item }) => <MerchantListItem merchant={item} onItemPress={()=>{
this.props.navigation.navigate('merchantDetail',{merchant: item})
}}/>}
keyExtractor={(item) => {
return `${item.id}`
}}
/>
</View>
)
}
and merchant list item:
class MerchantListItem extends React.PureComponent {
constructor(props) {
super(props);
}
render() {
let merchant = this.props.merchant
if(!merchant)
{
return <View/>
}
let name = merchant.name || ''
let address = merchant.address_summary || ''
let price = merchant.price || ''
let id = merchant.id || ''
let image_uri = `${NetworkManager.domain}/GetImageForMerchant/${id}`
// console.log(image_uri)
return <View style={styles.merchantListItemContainerView}>
<TouchableOpacity style={{flex: 1}} onPress={()=>{
if(this.props.onItemPress)
{
this.props.onItemPress()
}
}}>
<View style={{flex: 1, backgroundColor: 'black', alignItems: 'center', justifyContent: 'center'}}>
<Image source={{uri: image_uri}} style={{width: '100%', height: '100%', position: 'absolute', opacity: 0.4}}></Image>
{/* <Image source={require('../../assets/Images/DiscountImages/0.jpg')} style={{flex: 1, position: 'absolute', opacity: 0.5}}/> */}
<View style={{flex: 1, position: 'absolute'}}>
<Text style={styles.merchantListItemText}>
{name}
</Text>
<Text style={styles.merchantListItemSubText}>
{address}
</Text>
<Text style={styles.merchantListItemSubText}>
{price}
</Text>
</View>
</View>
</TouchableOpacity>
</View>
}
}
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.
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>