2016-11-30 256 views
0

我在我的组件中有一个多行textInput,我根据状态设置初始值。基于内容大小设置多行textInput的初始大小

我已经设置了一个onChange事件处理程序,它基于包装文本的高度正确调整字段的高度。但只有在手动输入字段时才会调用它。

所以我想弄清楚如何从textField的初始文本中获取计算出的内容高度。

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

我刚刚开始使用RN文档中的AutoExpandingTextInput示例,该示例使用状态来存储高度。我不确定如何可靠地计算文本的高度。这将取决于字体大小,重量,字母宽度等。 textInput组件中的某个位置,它已经知道其内容的计算高度,因为它位于传递给onChange的nativeEvent对象上。我的问题是访问该高度,而不是onChange。 –

+0

使用componentwillmount函数。你可以在componentwillmount函数中调用handleTextInputChange –

回答

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'很适合设置初始高度 –