2016-11-30 2 views
0

У меня есть многострочный textInput в моем компоненте, и я устанавливаю начальное значение на основе состояния.установить начальный размер многострочного текстаInput, основанный на размере содержимого

Я установил обработчик события onChange, который правильно регулирует высоту поля в зависимости от высоты обернутого текста. Однако он вызывается только при вводе вручную в поле.

Так что я хотел бы выяснить, как получить вычисленную высоту контента из текстового поля с его исходным текстом.

class MyComponent extends Component { 

    _textInput:any; 

    constructor(props) { 
     this.handleTextInputChange= this.handleTextInputChange.bind(this) 
     this.handleLayout= this.handleLayout.bind(this) 
     this.state.text = "The quick brown fox jumped over the lazy dog" 
    } 

    handleTextInputChange(evt){ 
     // This works, but only fires on manual input 
     const height = Math.max(35, evt.nativeEvent.contentSize.height) 
     this.setState({text: evt.nativeEvent.text, contentHeight:height}) 
    } 

    handleLayout(evt){ 
     // I can't seem to get anything useful from this event 
    } 

    componentDidMount(){ 
     for (key in this._textInput) console.log(key) 
     // I can't get anything useful from the 
     // _textInput object itself either 
    } 

    render() { 

     return(
      <TextInput 
      ref={textInput => (this._textInput = textInput)} 
      multiline={true} 
      onChange={this.handleTextInputChange} 
      onLayout={this.handleLayout} 
      style={{height: this.state.contentHeight}} 
      value={this.state.text} 
      /> 
      ) 
    } 
} 

Примечание: onContentSizeChange не используется, поскольку это, кажется, сломана в RN 0,38

+0

только вопрос: почему вы бы сохранить высоту содержимого в состоянии? Разве это не производные данные? Может быть, просто (я не знаю деталей) вы всегда можете вычислить высоту ввода (в 'render'), поэтому нет никакой разницы, если вы измените его значение вручную, если это первый рендер или изменение было вызвано в некоторых других путь. Это имеет смысл для вас? –

+0

Я только что начал с примера AutoExpandingTextInput в документах RN, который использует состояние для хранения высоты. Я не уверен, как правильно вычислить высоту текста. Это будет зависеть от размера шрифта, веса, ширины букв и т. Д. Где-то в компоненте textInput он уже знает вычисленную высоту своего содержимого, потому что он находится на объекте nativeEvent, который передается onChange. Моя проблема заключается в доступе к этой высоте, а не в onChange. –

+0

использование компонентwillmount функция. Вы можете вызвать handleTextInputChange в функции componentwillmount –

ответ

0

решена путем регулярного Text элемента с теми же свойствами стиля и используя его onLayout обратного вызова, чтобы установить высоту TextInput , Для правильного выравнивания потребовалось несколько дополнений.

Вот соответствующие части:

handleTextLayout(evt){ 
    this.setState({contentHeight:evt.nativeEvent.layout.height+12}) 
} 

handleTextInputChange(evt){ 
this.setState({text: evt.nativeEvent.text}) 
} 

renderTextInput(){ 
    return(
     <View style={{flex:1, flexDirection:"row", flexGrow:1}}> 

     <Text 
     onLayout={this.handleTextLayout} 
     style={ 
      [styles.textInput, {color: "blue", paddingLeft:4, paddingRight:4}] }> 
      {this.state.text} 
      </Text> 

      <TextInput 
      multiline={true} 
      onChange={this.handleTextInputChange} 
      style={[styles.textInput, {position:"absolute", top:0, left:0, right:0,height: this.state.contentHeight} ]} 
      value={this.state.text} 
      /> 
      </View> 
      ) 
} 

Решение было вдохновленные this github issue

+0

Пришел к этому вопросу, когда у меня была схожая проблема, и пытался найти решение. Я обнаружил, что 'onContentSizeChange' хорошо работает для установки начальной высоты –

Смежные вопросы