React Native, the most widely used framework for building cross-platform applications which combines the best parts of native development with , a Javascript library for making user interfaces.
So, with the cross-platform iOS & Android support there comes a wide variety of devices having different resolutions. The user interface has to be designed in such a way that the application looks somewhat similar throughout the range of devices.
While developing a React Native app I came across multiple issues for this particular scenario:
- Fonts looks really small & unreadable for bigger devices.
- Solution: Font Scaling. - When device fonts has been scaled by system settings to the extent which breaks the UI of whole App.
- Solution: Restrict Device Font Scaling.
Font Scaling
For making the UI look according to the size of device we have to scale the font accordingly. So we use the device height, width & pixel ratio to calculate the font size to be used.
Below are the Functions that can used as per the needs to scale the fonts:
import { Platform, PixelRatio, Dimensions } from 'react-native';
import ExtraDimensions from 'react-native-extra-dimensions-android'
import DeviceInfo from 'react-native-device-info';
import { isIphoneX } from 'react-native-iphone-x-helper'
const { width, height } = Dimensions.get("window");
export default class DeviceUiInfo {
static platform = Platform.OS; //gives the device platform iOS or Android
static screenSize = { width, height }; //gives the width & height of device
static screenSizeWithPixelRatio = { width: width * PixelRatio.get(), height: height * PixelRatio.get() }; //calculate the width & height based on device pixel ratio
static guidelineBaseWidth = 350; //standard width which will be used as base for calculating the scale.
static guidelineBaseHeight = 680; //standard height which will be used as base for calculating the scale.
static isIphoneX = isIphoneX() //check if device is iPhoneX
static isTablet = DeviceInfo.isTablet() //check if device is Tablet
static appVersion = DeviceInfo.getVersion(); //gives app version
static softBarHeight = ExtraDimensions.get('SOFT_MENU_BAR_HEIGHT'); //gives soft menu bar height
static statusBarHeight = ExtraDimensions.get('STATUS_BAR_HEIGHT'); //gives status bar height
static fontScale = PixelRatio.getFontScale() //gives font scale based on pixel ratio
static getPlatform() {
return this.platform
}
static getScreenSize() {
return this.screenSize
}
static getScreenSizeWithPixelRatio() {
return this.screenSizeWithPixelRatio
}
static isIphoneX() {
return this.isIphoneX
}
static scale(size) {
return this.screenSize.width / this.guidelineBaseWidth * size;
}
static verticalScale(size) {
return (this.screenSize.height) / this.guidelineBaseHeight * size;
}
static moderateScale(size, factor = 0.5) {
return size + (this.scale(size) - size) * factor;
}
static actualScale(size) {
const inputSize = DeviceUiInfo.moderateScale(size)
return inputSize / this.fontScale
}
}
Restrict Device Font Scaling
To solve the unnecessary Font Scaling set by the device settings, we have to override the font scaling.
Here were are using NativeBase framework for UI components so we will be overriding it’s Text component for example and also the Text component which is provided by react-native.
if (Text.defaultProps == null) Text.defaultProps = {};
if (NBText.defaultProps == null) NBText.defaultProps = {};
Text.defaultProps.allowFontScaling = false;
NBText.defaultProps.allowFontScaling = false;
TextInput.defaultProps.allowFontScaling = false
These are the few solutions for the issues we can handle. Open to suggestions for the same. If you like then share & subscribe to the blog.
Originally published at http://blog.logicwind.com on February 8, 2020.