React Native - how to set a fixed width for individual characters (number, letter, etc.)

I have a problem in the React Native application that I am creating. I have a stopwatch, and since each numeric character has a different width, as time increases, the text starts moving everywhere, as opposed to staying in measure with a fixed width.

For example, if you have an iOS mobile device, open the default clock app that comes with it and use your stopwatch. You will notice that each character in the 00:00:00 series has a fixed width, or at least it seems so. If one of 0 turns into 1, although it would seem that 1 has a smaller width, it still takes up the same amount of space, and therefore the text does not jump over all the places.

However, in my React Native app this is not the case. 1 takes up less width than 0 or any other number, so it makes the text jump everywhere and it is really annoying.

Here is a good, working version (note how, with every change in the number, the width of the "container" in which the number is located never changes?) This ensures a smooth transition:

enter image description here

Now take a look at my version of the disaster:

enter image description here

I can not find a solution to this problem.

I feel that one way to solve this problem is to place each character in a separate <Text> with a given width, but I know that will be redundant. There should be an easier way to do this.

Any guidance would be appreciated.

+9
source share
3 answers

Thanks to @ppeterka, I found a very simple solution for this that requires a single line of code: use a monospace font.

Here is a list of some available monospaced fonts that come with iOS:

Courier

Courier-Bold

Courier-BoldOblique

Courier-Oblique

Courier New

CourierNewPS-BoldItalicMT

CourierNewPS-BoldMT

CourierNewPS-ItalicMT

CourierNewPSMT

Menlo Fat

Menlo-BoldItalic

Menlo Italic

Menlo Regular

+10
source

Although the question is flagged for iOS, if someone is looking for a universal solution that supports monospaced text on iOS and Android (as I did), then there is an additional resource for you!

Font selection:

responsive native-training / responsive-native-fonts on github has a good list of fonts that are on every platform. As you can see, there are no matches between monospaced fonts that the OPs provided in their answer . However, Android has a font called "monospace" that will work for this use case.

OS conditional expression

Since reacting to the native will cause an error if the font in fontFamily does not exist, we will need to conditionally install fontFamily depending on what is available in the OS. Reaction-native's Platform.OS can be used to determine the device OS.

example

 // components/TextFixedWidth.js import React from 'react' import { Platform, Text } from 'react-native' export default function TextFixedWidth ({ children }) { const fontFamily = Platform.OS === 'ios' ? 'Courier' : 'monospace' return ( <Text style={{fontFamily}}>{ children }</Text> ) } 

then

 // in a render method somewhere in the app <TextFixedWidth> Any monospace text you want! </TextFixedWidth> 

I hope this is helpful :)

+6
source

The system font in iOS is San Francisco, which by default has proportional numbers, but contains an option for fixed-width numbers (monospaced). In fontVariant you should use the fontVariant property for your Text component style:

 <Text style={{fontVariant: ['tabular-nums']}}> 1,234,567,890.12 </Text> 

It was difficult for me to find it, because the name is not explicit, and not what is commonly used. Here is a link to the text details in the RN document: https://facebook.imtqy.com/react-native/docs/text.html#style

0
source

All Articles