【问题标题】:How would I grow <TextInput> height upon text wrapping?如何在文本换行时增加 <TextInput> 高度?
【发布时间】:2015-10-12 01:26:38
【问题描述】:

我正在尝试创建一个&lt;TextInput&gt;,当文本换行到下一行时,它的高度会增加,类似于 Slack 的消息输入如何随着文本达到一个点而增长。

我有 multiline 道具集,所以它正在包装,但文档似乎没有提到任何关于包装的事件,我唯一能想到的是一个非常老套的字符计数策略,以确定何时增加输入的高度。我将如何做到这一点? https://facebook.github.io/react-native/docs/textinput.html

【问题讨论】:

标签: react-native


【解决方案1】:

感谢 react-native 文档:https://facebook.github.io/react-native/docs/textinput.html

你可以这样做:

class AutoExpandingTextInput extends React.Component {
  state: any;

  constructor(props) {
    super(props);
    this.state = {text: '', height: 0};
  }
  render() {
    return (
      <TextInput
        {...this.props}
        multiline={true}
        onChange={(event) => {
          this.setState({
            text: event.nativeEvent.text,
            height: event.nativeEvent.contentSize.height,
          });
        }}
        style={[styles.default, {height: Math.max(35, this.state.height)}]}
        value={this.state.text}
      />
    );
  }
}

0.46.1 或更高:(由 Nicolas de Chevigné 解释)

class AutoExpandingTextInput extends React.Component {

  constructor(props) {
    super(props);
    this.state = {text: '', height: 0};
  }
  render() {
    return (
      <TextInput
        {...this.props}
        multiline={true}
        onChangeText={(text) => {
            this.setState({ text })
        }}
        onContentSizeChange={(event) => {
            this.setState({ height: event.nativeEvent.contentSize.height })
        }}
        style={[styles.default, {height: Math.max(35, this.state.height)}]}
        value={this.state.text}
      />
    );
  }
}

【讨论】:

  • 这是一个很好的答案。但我的问题是:我有两个文本输入字段,我使用上面的答案。当我在一个文本输入字段中输入内容时,另一个文本也会同时增长。可以做些什么来解决这个问题,以便一次只增长一个文本输入?
  • 您是否在两个输入中使用相同的状态值?就像在onChange 中一样,当您使用setState 时,为每个人创建一个唯一的键,例如textUsernameheightUsername 并在value 道具和样式中使用它,对其他输入执行相同的操作,这一个人会独自成长。
  • @Satan 有点晚了,但是您需要使用 AutoExpandingTextInput 作为它自己的组件,而不是将其直接插入到您当前的组件中。
  • 当你删除行时它不会缩小
【解决方案2】:

由于 React Native 0.46.1

contentSize 属性已从 TextInput.onChange 事件中移除

如果你使用这个版本,你可以处理onContentSizeChangeprop

来自the Jérémy answer,我们有

class AutoExpandingTextInput extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
        text: '',
        height: 0
    };
  }

  render() {
    return (
      <TextInput
        {...this.props}
        multiline={true}
        onChangeText={(text) => {
            this.setState({ text })
        }}
        onContentSizeChange={(event) => {
            this.setState({ height: event.nativeEvent.contentSize.height })
        }}
        style={[styles.default, {height: Math.max(35, this.state.height)}]}
        value={this.state.text}
      />
    );
  }
}

【讨论】:

  • 谢谢!但是,如果我为输入 onContentSizeChange={(event) =&gt; { let currentHeight = event.nativeEvent.contentSize.height; if (currentHeight &gt; 100){ currentHeight = 100; } this.setState({ inputHeight: currentHeight }) }} 设置了最大高度并且其中有很多文本,那么在高度设置为 100 后它不会滚动到底部,如何解决这个问题?
  • 在 iphone 上一切正常,但在 android 上我有这个问题。
  • 当我按下 时,我正在让它工作,但在换行时不会。 contentSize.height 总是 14,只要我输入一个很长的行,它会换行几次;但只要我按 换行,它就会增加到 28。只有按 才会增加高度,而不是换行。
【解决方案3】:

您应该在style 中设置一个maxHeight 属性:

<TextInput multiline style={{maxHeight: 80}} />

在这里演示:https://snack.expo.io/@yairopro/multiline-input-with-max-height

【讨论】:

  • 不适用于需要使用 numberOfLines 更改默认高度的 Android(Android 上的不同行为)
【解决方案4】:

我的回答是在TextInput中使用onContentSizeChangenumberOfLines props,当然要开启multiline,这是我的解决方案:

let numOfLinesCompany = 0;
<TextInput
     ...
     multiline={true}
     numberOfLines={numOfLinesCompany}
     onContentSizeChange={(e) => {
         numOfLinesCompany = e.nativeEvent.contentSize.height / 18;
     }}
/>

18是文字的高度,大概取决于fontSize

【讨论】:

  • 你是如何计算 18 作为字体高度的。
【解决方案5】:
<TextInput multiline style={{maxHeight: ...}} />

【讨论】:

    【解决方案6】:

    我所做的是为输入最大高度设置视图,例如:

    messageBox: {
    maxHeight: 110,
    width: '80%',
    borderRadius: 10,
    padding: 10,
    backgroundColor: Color.White},
    

    并将输入设置为多行:

    <View style={[styles.messageBox, styles.managerMsg]}>
      <Input
        allowFontScaling={false}
        name="notes"
        blurOnSubmit={false}
        onChangeText={notes => console.log(notes)}
        returnKeyType="go"
        onSubmitEditing={() => Keyboard.dismiss()}
        multiline
      />
    </View>
    

    这个“Input”只是一个简单的自定义组件,它接收所有的 Props。

    【讨论】:

      【解决方案7】:

      你不妨试试这样的。

      <TextInput style={[styles.inputs,{height: Math.max(35, this.state.height)}]}
                      placeholder="Write a message..."
                      multiline={true}                
                      onChangeText={(msg) => this.setState({ text: msg })}
                      onSubmitEditing={Keyboard.dismiss}
                      onContentSizeChange = {() => this.scrollView.scrollToEnd({animated:true})}
                     
                    />
      

      style.inputs

        inputs: {
          
          minHeight:40,
          marginLeft: 16,
          paddingTop: 10,
          overflow:'hidden',
          padding: 15,
          paddingRight: 25,
          borderBottomColor: '#000000',
          flex: 1,
          position: 'absolute',
          width: '100%',
      
      
        },
      

      当文本超过一行时,会在文本输入字段中创建一个滚动视图并自动滚动到底部。当内容增长时,这实际上不会增加​​文本输入的高度,而是在输入字段中创建滚动视图。服务于目的。 我发布了我的解决方案,因为其他人对我不起作用(文本输入大小在键盘后面增长,并且存在文本溢出问题)。 因此,对于遇到与我类似的问题的任何人,希望这对您有用。

      【讨论】:

        【解决方案8】:
        <View style={{flex:1}}>
            <TextInput
                multiline={true} />
        </View>
        

        【讨论】:

          【解决方案9】:

          你也可以像这样使用 onChangeText 来设置 TextInput 的高度。

            const textHeight = 19 //fontsize of the text
            <TextInput
            style={[styles.input, 
                   {height:Math.max(40,inputHeight)}]}
          
            onChangeText= {text => {
              const height = text.split("\n").length
              setInputHeight(height * textHeight)
            }}
          
            multiline
          />
          

          【讨论】:

            【解决方案10】:

            只需使用 multiline={true} 即可,无需设置高度。检查以下

            <SafeAreaView style={{flex:1, backgroundColor:"#F8F8F9"}}>
                    <ScrollView style={{flex:1}}>
                        {
                            this.state.data && <CommentListView data={this.state.data} onReplyClick={this.onReplyClick}/>
                        }
                    </ScrollView>
                    <View style={{bottom:Platform.OS=="ios" ? this.state.keyboardHeight : 0, flexDirection:"row", alignItems:"flex-end", padding:10}}>
                        <TextInput 
                        multiline={true}
                        style={{flex:3, backgroundColor:"#EFEFEF", borderRadius:5, padding:10}} 
                        value={this.state.comment} 
                        onChangeText={(text)=> this.setState({comment:text})}
                        />
                        <TouchableOpacity style={{flex:1}} onPress={()=> this.submit()}>
                            <Text style={{padding:13, color:"#fff", textAlign:"center", fontWeight:"bold", backgroundColor:"#00394D", borderWidth:1, borderColor:"#00FFEE", borderRadius:5, overflow: "hidden"}}>Post</Text>
                        </TouchableOpacity>
                    </View>
                </SafeAreaView>
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-10-13
              • 2014-12-14
              • 2018-06-21
              • 1970-01-01
              相关资源
              最近更新 更多