Reputation: 21
I'm trying to build an animated "See More/Discard" button in my React Native App. I was planning to use onLayout or onTextLayout methods to get the height of my text, then using animated and overflow: "hidden" to display it on click of a button. Here's what the code looks like :
<Animated.View style={{overflow: "hidden", height: heightAnim }}>
<Text
onTextLayout={({ nativeEvent: { lines } }) => {
//We set the maxHeight to number of lines * the height of a line
setContentHeight(lines.length * 14);
}}
>
{description}
//Description can range between 0 to 15 lines
</Text>
</Animated.View>
<TouchableWithoutFeedback onPress={() => handleOpen()}>
<Text>
{open ? "Discard" : "See More"}
</Text>
</TouchableWithoutFeedback>
However, onLayout and onTextLayout only give me the size of the text that is visible on the screen. To give you an example, if the text lasts 14 lines and I initially display 2 lines of height 14, onLayout will return a height of 28, and onTextLayout lines will only return me the 2 first lines. This result in the maxHeight of my animation being also 28, so the hidden text remains hidden.
How can I access the height of all the height/lines of my text, including the hidden part?
Thank you for your help!
Upvotes: 2
Views: 6555
Reputation: 498
You can use this simple way, it works fine but if you need to dynamically check if the text has more than 1 line you need to use onTextLayout
and check on it.
const [lines, setLines] = useState(1)
<View>
<Text numberOfLines={lines}>This is some long text here This is some long
text here This is some long text here This is some long text here This is
some long text here This is some long text here This is some long text here
This is some long text here This is some long text here This is some long
text here This is some long text here This is some long text here
</Text>
<TouchableOpacity onPress={() => {
lines == 999 ? setLines(1) : setLines(999)
}}>
<Text style={{ color: 'blue' }}>{lines == 999 ? "Less" : "More"}</Text>
</TouchableOpacity>
</View>
UPDATE:
or what you can do is wrap the text into the TouchableOpacity
and when press on it it will expand like this
const [lines, setLines] = useState(1)
<View>
<TouchableOpacity onPress={() => {
lines == 999 ? setLines(1) : setLines(999)
}}>
<Text numberOfLines={lines}>This is some long text here This is some long
text here This is some long text here This is some long text here This is
some long text here This is some long text here This is some long text here
This is some long text here This is some long text here This is some long
text here This is some long text here This is some long text here
</Text>
</TouchableOpacity>
</View>
Upvotes: 0
Reputation: 61
<View>
<ScrollView style={{height:0}}>
<Text onTextLayout={(e)=>{/* measure the text here */}}>{text}</Text>
</ScrollView>
<Text>{text}</Text>
</View>
you can render the text twice,one of the text wrapped with a ScrollView which height is 0. Then you can measure the all the height/lines of the text
Upvotes: 4