React Native Responsive View Iphone x - ios

I face a little problem while styling for Iphone X, I used widthPercentageToDP and heightPercentageToDP from react-native-responsive-screen to make the view similar, in most of the devices it worked perfectly except Iphone X, the difference is a little bit but I want to make the view accurate as possible.
<View style={styles.container}>
<ImageBackground source={require('../../assets/acc.png')} style={styles.bgImg}>
<View style={styles.headerView}>
<FontAwesome style={styles.setting} name="cog" size={hp('4%')} color="#6B6466" />
<Text style={styles.headerText}>My Account</Text>
</View >
<View style={styles.imgView} >
<Image source={require('../../assets/user.png')} style={styles.accImg}/>
<Text style={styles.name}> John doe</Text>
<Text style={styles.number}> 123456789</Text>
</View>
<View style={styles.bottomView}>
<View style={styles.bottomView2}>
<TouchableOpacity style={styles.inboxView}>
<Text style={styles.inboxNumber}>12</Text>
<Text style={styles.inboxText}>Inbox</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.inboxView}>
<Text style={styles.inboxNumber}>17</Text>
<Text style={styles.inboxText}>Sent</Text>
</TouchableOpacity>
</View>
</View>
</ImageBackground>
</View>
Style
const styles = StyleSheet.create({
container: {
flex: 1, backgroundColor: '#fff'
},
bgImg:{
height: hp('40%'), width: '100%'
},
setting:{
color:'white'
},
headerText:{
flex:1,textAlign:'center',fontSize:wp('5%'),fontFamily:Fonts.Cairo,marginRight:10,color:'white'
},
headerView:{
flexDirection:'row',justifyContent:'space-between',marginHorizontal:10,marginTop:hp('5%')
},
imgView:{
flex:1,
alignItems:'center'
},
accImg:{
height:wp('30%'),width:wp('30%'),borderRadius:wp('15%'),marginTop:wp('3%')
},
name:{
color:'white',fontFamily:Fonts.Cairo,fontSize:wp('4%'),textAlign:'center'
},
number:{
color:'white',fontSize:wp('4%'),textAlign:'center'
},
bottomView:{
flex:1,
justifyContent:'flex-end'
},
inboxNumber:{
color:'white',
textAlign:'center',
fontSize:wp('4%')
},
inboxText:{
color:'white',
textAlign:'center',
fontSize:wp('4%'),
fontFamily:Fonts.Cairo
},
bottomView2:{
flexDirection:'row',
justifyContent:'space-between',
marginHorizontal:10,
marginBottom:wp('3%')
},
});
Output

The Iphone X is rendering the real result, this is how your layout looks like, the other devices don't have enought space for rendering and they "overlap" the views ... Look at your views, you have an imagebackground wich takes 40% of the screen , inside you have a header wich will render normally since it's higher in the render function.
Below you have a view with flex :1 and inside an image with screen based values with 2 rows of text below , if the image is lager than the view it will push the text outside of the view , invading the below neighbour view
BELOW that you have a view with the 2 touchableopacitys . they should not be overlapping. In fact, try adding overflow:'hidden' to the imgView style
------header------
///////IMAGE////////
///////IMAGE////////
///////Johndo///////
///////12345////////
Button//////Button
Just like the iphone is showing
<ImageBackground source={require('../../assets/acc.png')} style={styles.bgImg}>
<View style={styles.headerView}>
//here is the header
</View >
<View style={styles.imgView} >
// below is the image , the name , and the number
</View>
<View style={styles.bottomView}>
//below it should be the 2 buttons , not overlapping, BELOW
</View>
</ImageBackground>

Related

Keyboard covers one of the inputs in my React Native where view is centered using justifyContent

So I have this react native code where I centered multiple inputs inside view, when I click the lower located input my keyboard seems to overrun it so I cannot see what I'm typing on my iOS simulator (iPhone 14). The error seems to be on iOS only and Android is fine. note that I also have bottom Navigation bar.
https://ibb.co/sV0Xk9L
<SafeAreaView style={{ flex: 1}}>
{...}
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View style={styles.profile_info}>
<KeyboardAvoidingView behavior={'position'} keyboardVerticalOffset={dimensions.height < 668 && phoneSelected ? 120 : 40}>
<ScrollView>
<View>
<Input />
<View/>
<View>
<Input />
<View/>
<View>
<Input />
<View/>
</ScrollView>
</KeyboardAvoidingView>
</View>
</TouchableWithoutFeedback>
</SafeAreaView>
{ // styling below }
function getProfileStyles(theme) {
return StyleSheet.create({
profile_info: {
flex: 1,
marginHorizontal: 20,
justifyContent: 'center',
},
});
}
I have tried using the solution found here https://stackoverflow.com/a/51169574/11288070 which uses #react-navigation/elements deps
import { useHeaderHeight } from '#react-navigation/elements'
something else that I do is changing from justifyContent to use topPadding: dimensions.height / 5 but it's not interactive.
Use:
KeyboardAwareScrollView from "react-native-keyboard-aware-scroll-view"
library instead of KeyboardAvoidingView

Give space between <text> components which is a child in a view component

import { Text, View, Image, StyleSheet } from 'react-native';
import * as react from 'react';
export default function TabOneScreen(){
return (
<View style={styles.container}>
<Image source = {{uri:'https://notjustdev-dummy.s3.us-east-2.amazonaws.com/avatars/elon.png'}} style={styles.image} />
my task is to give space to this text which is supposed to appear in a straight line (Elon Musk
11:11AM) using justifyContent: 'space-between' but its not having any effect instead the text are still together (Elon Musk11:11AM)
<View style={styles.row}>
<Text style={styles.name}>Elon Musk</Text>
<Text style={styles.text}>11:11 AM</Text>
</View>
<Text style={styles.text}>Boi Ice for Janet</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container:{
flexDirection:'row',
padding:10,
},
image:{
height:60,
width:60,
borderRadius:50,
marginRight:10,
},
name:{
fontSize:20,
color:'blue',
},
row:{
flexDirection:'row',
justifyContent: 'space-between',
},
text:{
fontSize:20,
color:'blue'
}
});
You would need to use a
row:{
flex:1
// other keys
}
and/or
row:{
width:'100%'
}
so that the view (row) covers the width of the screen.

React Native - Scrollview scrolls up with many inputs [iOS]

I have many inputs within ScrollView. Everytime I try to tap the Save button, if the last input focused is out of the screen view (where the Save button is), the screen scrolls automatically up to the input. However, if I scroll down again and press/tap the Save button again, it works. So I have to tap twice the button.
This only happens on iOS devices. On Android works perfectly.
Here is my code:
render() {
const keyboardVerticalOffset = Platform.OS === "ios" ? 40 : 0;
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : ""}
keyboardVerticalOffset={keyboardVerticalOffset}
style={styles.container}
>
<View
style={{
flexDirection: "column",
justifyContent: "space-between",
height: "100%",
backgroundColor: colors.white,
}}
>
<ScrollView
ref={(scroll) => (this.scroll = scroll)}
keyboardShouldPersistTaps={'handled'}
style={{
marginBottom: this.state.marginBottom,
paddingHorizontal: 20,
}}
>
<DateForm
onChangeDate={this.onChangeDate.bind(this)}
date={this.state.measureDate}
birthdate={this.state.baby.Birthdate}
/>
<MeasureForm
onChangeMeasure={this.onChangeValue.bind(this)}
value={this.state.value}
scrollTo={this.scrollTo.bind(this)}
/>
<ResultsForm
IC={this.state.indexes.IC}
IABC={this.state.indexes.IABC}
colorIC={this.state.indexes.colorIC}
colorIABC={this.state.indexes.colorIABC}
/>
<CBButton
title={global.loc.getTranslation("AddMeasureSaveButton")}
style={{
width: "100%",
marginHorizontal: 0,
flexGrow: 1,
marginTop: 20,
marginBottom: 50,
}}
disabled={!this.state.validForm}
onPress={() => this.disableButton()}
/>
</ScrollView>
</View>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
UPDATE
Here is a minimal reproducible example on snack

White Screen on top part of iOS react native

I get white screen at the top part of my iOS react native app. I have SafeAreaView as a container housing my code. On some screens the white space is just at the top, some others, just bottom; while some top and bottom. Below is an image:
Below is what my code looks like:
<SafeAreaView style={styles.container}>
<ImageBackground source={backgroundImg} style={styles.image}>
{/* arrow section */}
<TouchableOpacity
style={styles.firstLevelContainer}
onPress={() => navigation.goBack()}>
<Image source={backIcons} style={styles.backIconsStyle}></Image>
</TouchableOpacity>
{/* text Section */}
<View style={styles.secondLevelContainer}>
<CustomText
color={colors.white}
size={30}
capitalize={'none'}
fontType={fonts.nunitoBold}>
{CapitalizeFirstLetter('Create\nan account')}
</CustomText>
</View>
<View style={styles.thirdLevelContainer}>
<ScrollView
style={styles.scrollviewContainer}>
{Formikform()}
</ScrollView>
</View>
<View style={styles.fourthLevelContainer}>
<CustomText
color={colors.white}
size={12}
style={{marginLeft: 10}}
capitalize={'none'}
fontType={fonts.nunitoLight}>
or sign in with
</CustomText>
<View style={styles.displayRow}>
<Image
source={facebookLogo}
style={styles.socialLoginIconSize}></Image>
<Image
source={googleLogo}
style={styles.socialLoginIconSize}></Image>
</View>
</View>
</ImageBackground>
</SafeAreaView>
StyleSheet
container: {
flex: 1,
flexDirection: 'column',
top: 0,
},
formContainer: {
display: 'flex',
marginBottom:hp(20),
marginLeft:hp(5)
},
image: {
flex: 1,
resizeMode: 'cover',
},
That's exactly how SafeAreaView works. If you want your image to cover all of the screen I'd suggest the following UI Hierarchy:
<ImageBackground>
<SafeAreaView>
// your content goes here
</SafeAreaView>
</ImageBackground>
Checkout this snack for more details

TouchableHighlight one click not work two works

I am having a strange problem. I wrote up a simple player app with react native and everything is fine in simulator. But when it comes to real device, its play button does not work properly. I tried the app on iPhone 6s and iPhone 5. The problem is that the play button works at second tap. The first tap does nothing.
Here is my whole render code:
render() {
let playIcon = this.state.isPlaying ? 'pause' : 'play';
let titleA = 'Set A: ' + (this.state.isASet ? this._toTime(this.state.pointA) : '-');
let titleB = 'Set B: ' + (this.state.isBSet ? this._toTime(this.state.pointB) : '-');
let time = this._toTime(this.state.time);
let remaining = this._toTime(this.state.duration - this.state.time);
return (
<View style={styles.container}>
<View style={styles.info}>
<Text>Name: {this.props.song.name}</Text>
<Text>Artist: {this.props.song.artist.name}</Text>
<Text># of channels: {this.props.song.tracks.length}</Text>
</View>
<View style={styles.channels}>
{
this.props.song.tracks.map((track, index) => {
return (
<VolumeSlider
key={index}
title={track.name}
volume={this.state.channelVolumes[index]}
onVolumeChange={this._handleChannelVolumeChange.bind(this, index)}
onMutePress={this._handleChannelMutePress.bind(this, index)}
onSoloPress={this._handleChannelSoloPress.bind(this, index)}
isPlayingSolo={this.state.channelSolos[index]}
/>
);
})
}
<VolumeSlider
title='Main'
volume={this.state.mainVolume}
onVolumeChange={this._handleMainVolumeChange.bind(this)}
onMutePress={this._handleMainMutePress.bind(this)}
hideSolo={true}
/>
</View>
<View style={{flexDirection: 'row', justifyContent: 'center'}}>
<TouchableHighlight style={styles.button} onPress={this._handleAPress.bind(this)}>
<Text numberOfLines={1}>{titleA}</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.button} onPress={this._handleBPress.bind(this)}>
<Text numberOfLines={1}>{titleB}</Text>
</TouchableHighlight>
<TouchableHighlight
style={styles.button}
onPress={this._handleClearLoopPress.bind(this)}
>
<Text numberOfLines={1}>Clear</Text>
</TouchableHighlight>
</View>
<View style={styles.player}>
<TouchableHighlight onPress={this._handlePlayPress.bind(this)}>
<Icon
name={playIcon}
style={styles.playButton}
/>
</TouchableHighlight>
<View style={styles.center}>
<Text style={styles.timelineText}>{time}</Text>
</View>
<View style={styles.sliderContainer}>
<Slider
style={[styles.slider, styles.timelineSlider]}
onSlidingComplete={this._handleTimelineChange.bind(this)}
maximumValue={this.state.duration}
value={this.state.time}
step={0.01}
/>
</View>
<View style={styles.center}>
<Text style={styles.timelineText}>-{remaining}</Text>
</View>
</View>
</View>
);
}
And this is how it looks like on simulator:
I tried changing the location of the play button (I mean I placed it at the top of the app) and it worked. But I don't understand why it does not work when it is at bottom-left corner?
Thank you for your answers.
I found the problem. The problem is NavigatorIOS which is parent of the PlayerScreen of which render function is given belove. The navigator has swipe back gesture and it blocks the first tap on the play button. When I disabled the swipe back gesture of the navigator by falsing its interactivePopGestureEnabled pro, the play button properly worked.

Resources