aks94
aks94

Reputation: 405

Is it possible to know how many lines of text are rendered by React Native when using numberOfLines prop?

The React Native numberOfLines prop is very useful but I want to programmatically adjust the height of my row between two numbers based on how many lines of text are actually rendered.

For example, I have a Text component of this form <Text numberOfLines={2} ellipsizeMode={'tail'}>{item.text}</Text>

If the text is longer than two lines, it defaults to two lines as desired. But when it is less than two lines, it just shows a single line, again as desired. I just want to know when the content is a single lien versus two lines. Is there any way of finding this out?

Upvotes: 7

Views: 14176

Answers (3)

Eslam Adel
Eslam Adel

Reputation: 1189

possible answer here herehttps://stackoverflow.com/a/58632169/11816387

I want to provide a modern solution. There is now a onTextLayout event that includes an array of lines which can be determined what number of lines are being rendered. There's other details in the lines array like actual height and width of every line which can be further used to determine if the text is being truncated.

const NUM_OF_LINES = 5;
const SOME_LONG_TEXT_BLOCK = 'Lorem ipsum ...';

function SomeComponent () { 
  const [ showMore, setShowMore ] = useState(false);
  const onTextLayout = useCallback(e =>
    setShowMore(e.nativeEvent.lines.length > NUM_OF_LINES);
  }, []);

  return (
    <Text numberOfLines={NUM_OF_LINES} onTextLayout={onTextLayout}>
      {SOME_LONG_TEXT_BLOCK}
    </Text>
  );
}

Upvotes: 6

MikeL
MikeL

Reputation: 2894

If you don't mind using an npm package react-native-text-size will solve your problem.

From their docs:

const size = await rnTextSize.measure({
  text,             // text to measure, can include symbols
  width,            // max-width of the "virtual" container
  ...fontSpecs,     // RN font specification
})

"size" is not only the size, it has more info, one of which is lineCount, which is what you need.
Personally, I needed to send allowFontScaling: false in the fontSpecs, because we handle that internally.

Upvotes: 1

Timothy Alfares
Timothy Alfares

Reputation: 317

In React Native, Text component has a props called onLayout

http://facebook.github.io/react-native/docs/text.html#onlayout

with {nativeEvent: {layout: {x, y, width, height}}}

So first, have a state

state = {
  numOfLines: 0
}

Then in your Text component

<Text 
  numberOfLines={this.state.numOfLines}
  onLayout={(e) => { 
    this.setState({ numOfLines: e.nativeEvent.layout.height > YOUR_FONT_SIZE ? 2 : 1 })
  }
>
  {item.text}
</Text>

I am not totally sure with this solution because I just think it from my mind straight away. But, my logic is if your text height is more than your text fontSize it means that it is more than one line?

Let me know if it is work or not

Upvotes: 2

Related Questions