React Native App design is different in different IOS Device - react-native

Hy everyone, I'm building a react native applications but I'm facing a issue for long time which is that the app design is different in iOS devices. The devices work iPhone 6-iphone 8 design is same and iPhone X - iPhone 13 is same. But these both groups are different in design.

When you say they are different in design, do you mean their device dimensions? If so, there are some workarounds for that issue. Personally, I would recommend creating scale functions for the width and height of the device you use to develop your app. Applying the scale functions will keep your design consistent throughout different devices.
import {Dimensions, PixelRatio} from 'react-native';
const {width: SCREEN_WIDTH, height: SCREEN_HEIGHT} = Dimensions.get('window');
// based on iphone 11s's scale
const scalew = SCREEN_WIDTH / 828;
const scaleh = SCREEN_HEIGHT / 1792;
export function normalizeh(size) {
const newSize = size * scaleh;
return Math.round(PixelRatio.roundToNearestPixel(newSize));
}
export function normalizew(size) {
const newSize = size * scalew;
return Math.round(PixelRatio.roundToNearestPixel(newSize));
}
Then when styling,
menuBtn: {
width: normalizew(60),
color: '#212529',
marginRight: normalizew(30),
},

Related

How to handle responsive design in expo

I am using react native expo and trying to make a app. But as the window size increase my each view get distorted i am using
marginTop:'33%'
but as i am expanding browser in right hand size then all my views starts going down. How can i manage responsive ness
I have also tried
import { Dimensions } from "react-native";
const { width, height } = Dimensions.get("window");
//Guideline sizes are based on standard ~5" screen mobile device
const guidelineBaseWidth = 390;
const guidelineBaseHeight = 844;
const screenSize = Math.sqrt(width * height) / 100;
const scale = size => (width / guidelineBaseWidth) * size;
const verticalScale = size => (height / guidelineBaseHeight) * size;
const moderateScale = (size, factor = 0.5) =>
size + (scale(size) - size) * factor;
export { scale, verticalScale, moderateScale, screenSize };
In this i am using moderateScale but not getting any good benefit from it. So please check and let me how can i make apps to show on web as well as mobile size.

For What people need this line of Code (Device Height)?

I have seen this line of code:
import { Dimensions, Platform } from 'react-native';
const { height, width } = Dimensions.get('window');
const deviceUtils = (function () {
const iPhone6Height = 667,
iphoneSEHeight = 568,
iPhoneXHeight = 812,
iPhoneXWidth = 375;
return {
dimensions: {
height,
width,
},
iPhone6Height,
iphoneSEHeight,
iPhoneXHeight,
iPhoneXWidth,
isIOS14: ios && parseFloat(Platform.Version as string) >= 14,
isLargePhone: width >= iPhoneXWidth,
isNarrowPhone: width < iPhoneXWidth,
isSmallPhone: height <= iPhone6Height,
isTallPhone: height >= iPhoneXHeight,
isTinyPhone: height <= iphoneSEHeight,
};
})();
export default deviceUtils;
I want to ask you why People need this exact height of iPhones ?
It seems someone plans to write different code for “wide” and “narrow” and “wide”, and for three different classes of heights. They use the exact width / height of an iPhone X for example to make sure that an iPhone X falls into the wide and tall categories.
This is not usually what you should do. Decide what you want to be on a screen. Use constraints to fit everything. If you have problems fitting everything use a smaller font or an adjustable font, or put everything in a scroll view. Anyway, with notch and things at the bottom of the screen, things are more complicated than just “width” and “height”.

Expo Three.js OrbitControls

I am trying to make a native app using expo in which I want to have a plane that I can pan around and zoom in and out of like a map, I am using Three as my 3d engine as I do need it to have the ability to be rotated in a 3d space. I have got a 3d cube in my app rotating as a start. From what I can tell this is pretty simple in a browser using MapControls or Orbit controls, however in native I can't get either of these things working, even when I import the script directly from the examples folder
export default function MapBuilder() {
const onContextCreate = async gl => {
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
75,
gl.drawingBufferWidth / gl.drawingBufferHeight,
0.1,
1000
)
const renderer = new ExpoTHREE.Renderer({ gl })
renderer.setSize(gl.drawingBufferWidth, gl.drawingBufferHeight)
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshNormalMaterial({ wireframe: true })
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)
const controls = OrbitControls(camera, renderer.domElement)
camera.position.y = 0
camera.position.x = 0
camera.position.z = 5
controls.update()
const animate = () => {
window.requestAnimationFrame(animate)
cube.rotation.x += 0.02
cube.rotation.y += 0.02
renderer.render(scene, camera)
controls.update()
gl.endFrameEXP()
}
animate()
}
return (
<GLView
style={{ flex: 1, backgroundColor: 'black' }}
onContextCreate={onContextCreate}
/>
)
}
I belive the issue could be the renderer.domElement but I dont know what to replace this with.
Any help is appreciated.
I misunderstood the question before
Sorry for the wrong answer
I also had problem with using OrbitControls in Expo today,
and found expo-three-orbit-controls works fine for me
I tested with my iPhone and Android emulator
try using ExpoGraphics.View instead of GLView
I have succeeded making a globe and running it on my iPhone by using expo-three and expo graphics
You can check the core of the source from here:
https://github.com/cryslub/history-expo/blob/master/ThreeScene.js

React Native: Radial Gradient Background

Is there an package, or another way to have a simple, let's say blue to blueish, radial gradient background, for one of the views?
I've tried react-native-radial-gradient, but it seems like it's outdated.
Probably you can use RadialGradient from my react-native-image-filter-kit package. Note that gradients from react-native-image-filter-kit are initially designed as primitives for blending with other images and your case is not something that was taken into account in the first place.
import { Image } from 'react-native'
import {
RadialGradient,
ImageBackgroundPlaceholder
} from 'react-native-image-filter-kit'
const imageStyle = { width: 320, height: 320 }
const gradient = (
<RadialGradient
colors={['red', '#00ff00', 'blue']}
stops={[0, 0.5, 1]}
image={
<ImageBackgroundPlaceholder style={imageStyle}>
/* your content here */
</ImageBackgroundPlaceholder>
}
/>
)

How to use React Native PixelRatio utility class?

I have an app written initially for iPhone 6 symulator which has a componend syled with following example values:
const styles = StyleSheet.create({
headerNav: {
width: 40,
height: 40
},
headerLogoImage: {
width: 140,
height: 140
},
footerNavText: {
padding: 15,
fontSize: 25
}
});
Unfortunately when I launched the app on iPad symulator, the size proportions completely collapsed. I know that there is something like PixelRation but documentation is very limited and unclear.
Any idea / suggestions how can I translate these width / height / padding & fontSize to proper values using this PixelRatio class?
fontSize needs to be divided by PixelRatio.getFontScale(). This will account for different screen densities in iOS and Android.
footerNavText: {
fontSize: 25 / PixelRatio.getFontScale()
}
https://facebook.github.io/react-native/docs/pixelratio.html
You could do something like:
footerNavText: {
padding: PixelRatio.get()*3,
fontSize: PixelRatio.get()*4
}
Check what get() method returns for each of the devices you wish to use and style accordingly.
For more info visit https://facebook.github.io/react-native/docs/pixelratio.html
// create this utils.ts file
import { PixelRatio } from "react-native";
// dp(123) converts 123px (px as in your mockup design) to dp.
export const dp = (px: number) => {
return px / PixelRatio.get();
};
// sp(54) converts 54px (px as in your mockup design) to sp
export const sp = (px: number) => {
return px / (PixelRatio.getFontScale() * PixelRatio.get());
};
Use it like the following way in your styles
const styles = StyleSheet.create({
footerNavText: {
padding: dp(123),
fontSize: sp(54)
}
})
Note
Do not use dp for fontSize. dp just depends on device screen density (dpi)
sp is used for fontSize only. sp is also just like dp but the difference is that it also depends on user's font settings in his device along with the device screen density (dpi).