Reputation: 397
I am adapting a React Native app from iPhone to iPad and I am facing a weird problem. I suspect of a bug with RN.
When user is in landscape mode and launches the app, it will have a Splash Screen in landscape mode, and there is no problem with that. But the app keeps recognizing Dimensions.get('window').width
as the width of landscape mode width even after I lock screen to portrait.
My app structure goes like this. The mother component of the app has a code that lock the app in portrait mode, like this:
var Orientation = require('react-native').NativeModules.Orientation;
componentWillMount(){
Orientation.lockToPortrait();
}
From that initial component other components are loaded via a router react-native-router-flux
. Inside those component UI components were styled using React Native Dimensions API. like this:
<View style={{ width: Dimensions.get('window').width - 10}} />
It works perfectly on iPhones, because iPhones are always on Portrait mode during app launch. But on iPads, when the user has his screen on landscape mode (during app launch), the entire app looks weird because RN is reconizing the screen height as the screen width. When the user launches the app while in portrait mode, the same problem won't happen. It should not be happening since the Dimensions.get('window').width
are being called just after the app is already locked to portrait. It makes no sense to me...
Unhappily I really need to be able to have landscape mode too, since inside some screens I force the user to be on landscape mode, by doing Orientation.lockToLandscape()
Any solutions to this problem?
Upvotes: 2
Views: 4135
Reputation: 499
I used this workaround based on pedrosimao answer:
Dimensions.addEventListener('change', e => {
const{width,height}=(e.window)
const getHeight = (percentage) => {
if (width > height) {
this.setState({orientation:'landscape'})
return ((height * percentage) / 100)
}else{
this.setState({orientation:'portrait'})
}
return height
}
this.setState({width:width,height:height,height2:getHeight(50)})
});
of course this don't works if you don't change the orientation at least once. You must use some initial state like this:
this.state={
height2: (Dimensions.get('window').height>Dimensions.get('window').width) ? Dimensions.get('window').height :(Dimensions.get('window').height*50)/100 ,
}
Upvotes: 1
Reputation: 397
I have come up with a hack in order to get my app working quickly, but I don't think this is the best method. I basically measure the screen to know in which orientation my app got locked. Like this:
const getWidth = (percentage: number) => {
if (Dimensions.get('window').width > Dimensions.get('window').height) {
return (Dimensions.get('window').height * percentage) / 100;
}
return (Dimensions.get('window').width * percentage) / 100;
};
const getHeight = (percentage: number) => {
if (Dimensions.get('window').width > Dimensions.get('window').height) {
return (Dimensions.get('window').width * percentage) / 100;
}
return (Dimensions.get('window').height * percentage) / 100;
};
After that I can create Stylesheet.create() objects that adapt to the screen orientation. Like this:
StyleSheet.create({
fullWidth: {
width: getWidth(100) - 60,
}
})
instead of:
StyleSheet.create({
fullWidth: {
width: Dimensions.get('window').width - 60,
}
})
Upvotes: 2