YiFeng
YiFeng

Reputation: 981

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!

Upvotes: 14

Views: 11133

Answers (2)

oar.garuna
oar.garuna

Reputation: 472

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

Upvotes: 4

tohster
tohster

Reputation: 7093

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.

Upvotes: 17

Related Questions