Reputation: 405
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
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
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
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