Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate the width of the text in a TextInput component in React Native?

I was trying to make the TextInput to be auto scaling, that is, the height of the TextInput increases as the text is wrapped to next line.

So I'm trying to calculate the width of the text, and compare it width the width of the TextInput. If it's greater than the width, the height of the TextInput will increase.

So my question is how to calculate the width of the text? Are there any other ways to accomplish the auto scaling effect?

Thanks!

like image 747
YiFeng Avatar asked Aug 29 '15 10:08

YiFeng


People also ask

How know width of a view React Native?

You can directly use the Dimensions module and calc your views sizes. Actually, Dimensions give to you the main window sizes. import { Dimensions } from 'Dimensions'; Dimensions. get('window').

How do I change the size of TextInput in React Native?

Try setting the styling of TextInput to flex: 1 instead of getting the width. The Flex style will automatically fill your view and leave the padding blank.

How do you focus TextInput in React Native?

Two methods exposed via the native element are .focus() and .blur() that will focus or blur the TextInput programmatically.


2 Answers

Currently there is no easy way to get the inner content width of a TextInput.

React Native is badly in need of an autosizing text input like the one you describe. I could use one also, so when I find time I may try to write one.

In the meantime, here's a workaround for accomplishing what you describe:

  1. Create your TextInput with its initial (fixed) height.

  2. Create a cloned <Text> element somewhere offscreen (e.g. use absolute position) with the same style as the TextInput. This is easy to do thanks to the declarative nature of React's style attribute. Set the width to the same width as your TextInput.

    • If your TextInput has responsive width, you may want to look at onLayout, or measure to get the width, otherwise there are ways to automatically render the clone with the same width (e.g. place it in the same container but offscreen).
  3. Write an onChange handler for the TextInput which: (a) Updates the clone's any time the TextInput text changes (b) Measures the height of the clone (since <Text> elements autosize) (c) Sets the new height of the Textinput

Although this is kind of a pain, you only have to write it once. It can easily be encapsulated into a component (e.g. ) which you can then re-use with impunity.

like image 154
tohster Avatar answered Sep 18 '22 21:09

tohster


Though I'm not answering the question asked, I want to point out that the auto-scaling TextInput can be easily implemented in React Native 0.34.

class AutoScaleTextInput extends React.Component {

  constructor() {
    super();

    this.state = {
      inputHeight: 35
    };
  }

  render() {
    return (
      <TextInput
        multiline={true}
        style={{
          height: this.state.inputHeight
        }}
        onContentSizeChange={ this._onTextContentSizeChange }/>
    );
  }

  _onTextContentSizeChange = (event) => {
    this.setState({
      inputHeight: Math.min(event.nativeEvent.contentSize.height, 100)
    });
  }
}

See: TextInput#onContentSizeChange

Expo Snack example https://snack.expo.io/HkqE2AhAe

like image 26
oar.garuna Avatar answered Sep 18 '22 21:09

oar.garuna