Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用React Native创建多行扩展TextInput_Ios_Ios8_React Native - Fatal编程技术网

Ios 使用React Native创建多行扩展TextInput

Ios 使用React Native创建多行扩展TextInput,ios,ios8,react-native,Ios,Ios8,React Native,我正在使用react原生应用程序,需要一个TextInput,它的功能与iOS上“messages”应用程序中的textview类似。它应该以一行开始,然后优雅地扩展到更多行,直到达到某个限制(如5行文本),然后根据需要开始滚动到最新的行 查看了SlackTextViewController,但a)它似乎有很多我不想要的东西,b)我想尽量保持尽可能多的代码在React中(并且不符合objective-C/swift) Edit:只想强调我更喜欢上面提到的REACT(JAVASCRIPT)代码,而

我正在使用react原生应用程序,需要一个TextInput,它的功能与iOS上“messages”应用程序中的textview类似。它应该以一行开始,然后优雅地扩展到更多行,直到达到某个限制(如5行文本),然后根据需要开始滚动到最新的行

查看了
SlackTextViewController
,但a)它似乎有很多我不想要的东西,b)我想尽量保持尽可能多的代码在React中(并且不符合objective-C/swift)


Edit:只想强调我更喜欢上面提到的REACT(JAVASCRIPT)代码,而不是Objective-C或Swift。

实现
UITextView
的委托方法
textViewDidChange
,并使用rect

- (void)textViewDidChange:(UITextView *)textView {
  CGSize constraintSize = CGSizeMake(textView.frame.size.width, MAXFLOAT);
  CGRect textRect = [textView.text boundingRectWithSize:constraintSize
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                            attributes:@{NSFontAttributeName:textView.font}
                                               context:nil];
  NSLog(@"Frame:%@", NSStringFromCGRect(textRect));
  CGRect newRect = textView.frame;
  newRect.size.height = textRect.size.height;
  textView.frame = newRect;
}

今天我尝试了两种不同的方法。两者都不是最好的,但我想我会记录下我的努力,以防它们有所帮助。它们都有你想要的效果,尽管有时会因为异步通信而延迟

1) 屏幕外文本高度 所以就在TextInput下面,我添加了一个常规文本字段,具有相同的字体和填充等等。我在输入上注册了
onChange
侦听器,并调用了
setState({text:event.nativeEvent.text})
。该文本文件从州政府获得了其价值。两人都有
onLayout
监听器。基本上,目标是从(不受限制的)文本中获取TextInput的高度。然后我把文字隐藏在屏幕外

2) 本机模块 真的,我只需要真实UITextView中内容的高度。因此,我向RCTUIManager添加了一个类别,因为已经有几种方法非常有用。我去掉了隐藏的文本视图。所以,
onChange
,我询问高度,并通过状态以相同的方式使用它

3) Github公共关系 我真正希望的是这份公关被接受。它看起来会自动执行类似的操作


多行={true}
添加到文本输入将允许在文本量超过可用空间时滚动。然后,您可以通过从onChange道具访问事件的nativeEvent.contentSize.height来更改TextInput的高度

class Comment extends Component {
   state = {
      text: '',
      height: 25
   }

   onTextChange(event) {
     const { contentSize, text } = event.nativeEvent;

     this.setState({
        text: text,
        height: contentSize.height > 100 ? 100 : contentSize.height
     }); 
   }

   render() {
      return (
         <TextInput
            multiline
            style={{ height: this.state.height }}
            onChange={this.onTextChange.bind(this)}
            value={this.state.text}
         />
      );
   }
}
类注释扩展组件{
状态={
文本:“”,
身高:25
}
onTextChange(事件){
const{contentSize,text}=event.nativeEvent;
这是我的国家({
文本:文本,
高度:contentSize.height>100?100:contentSize.height
}); 
}
render(){
返回(
);
}
}

从2017年10月起,Wix有一个很好的组件来实现这一点:

用法可以非常简单:

<AutoGrowingTextInput
  style={styles.textInput}
  placeholder="Enter text"
  value={this.state.text}
  onChangeText={this._handleChangeText}
/>

还有一些额外的道具,比如
minHeight
maxHeight


我在RN 0.47.2上使用它,另一个解决方案是检查
'\n'
符号并设置
numberOfLines
属性。 对我有用

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {TextInput} from 'react-native';

export default class TextInputAutogrow extends Component {

    constructor(props) {

        super(props);

        this._ref = null;

        this.bindRef = this.bindRef.bind(this);
        this.onChangeText = this.onChangeText.bind(this);

        this.state = {
            numberOfLines: this.getNumberOfLines()
        };
    }

    bindRef(c) {

        this._ref = c;

        this.props.innerRef && this.props.innerRef(c);
    }

    getText() {

        return typeof this.props.value === 'string' ?
            this.props.value :
            (
                typeof this.props.defaultValue === 'string' ?
                    this.props.defaultValue :
                    ''
            );
    }

    getNumberOfLines(value) {

        if (value === undefined) {

            value = this.getText();
        }

        return Math.max(this.props.numberOfLines, value.split('\n').length - 1) + 1;
    }

    onChangeText(value) {

        this.setState({numberOfLines: this.getNumberOfLines(value)})
    }

    render() {

        return (
            <TextInput
                {...this.props}
                ref={this.bindRef}
                numberOfLines={this.state.numberOfLines}
                onChangeText={this.onChangeText}
            />
        )
    }
}

TextInputAutogrow.propTypes = {
    ...TextInput.propTypes,
    innerRef: PropTypes.func,
};

TextInputAutogrow.defaultProps = {
    numberOfLines: 4,
};
import React,{Component}来自'React';
从“道具类型”导入道具类型;
从“react native”导入{TextInput};
导出默认类TextInputAutogrow扩展组件{
建造师(道具){
超级(道具);
此参数为.\u ref=null;
this.bindRef=this.bindRef.bind(this);
this.onChangeText=this.onChangeText.bind(this);
此.state={
numberOfLines:this.getNumberOfLines()
};
}
bindRef(c){
这个._ref=c;
this.props.innerRef&&this.props.innerRef(c);
}
getText(){
返回this.props.value=='string'的类型?
此.props.value:
(
typeof this.props.defaultValue==='string'?
this.props.defaultValue:
''
);
}
getNumberOfLines(值){
如果(值===未定义){
value=this.getText();
}
返回Math.max(this.props.numberOfLines,value.split('\n')。长度-1)+1;
}
onChangeText(值){
this.setState({numberOfLines:this.getNumberOfLines(value)})
}
render(){
返回(
)
}
}
TextInputAutogrow.propTypes={
…TextInput.propTypes,
innerRef:PropTypes.func,
};
TextInputAutogrow.defaultProps={
行数:4,
};

@Groovietunes几乎所有的答案都是正确的,但截至19年6月26日,情况与最初的答案有所不同

首先,textinputs上的
onChange
属性不再返回
contentSize
对象,因此
event.nativeEvent.contentSize
将返回
未定义的

解决方法是使用
onContentSizeChange
prop。但是有一个陷阱
onContentSizeChange
在安装组件时仅运行一次,因此无法在组件更改时动态获取高度

要解决这一问题,我们需要确保在支柱层次结构中的
onContentSizeChange
之后设置
支柱,以便在
textinput
增长时不断获取内容大小

在这一切结束时,我有一个组件,看起来像这样

<TextInput
        placeholder={this.props.placeholder}
        autoFocus={this.props.autoFocus}
        style={[
          styles.inputFlat,
          { height: this.state.height > 40 ? this.state.height : 40 }
        ]}
        ref="inputFlat"
        onFocus={() => {
          this.toggleInput();
          this.toggleButton();
        }}
        multiline={this.props.multiline}
        onBlur={() => {
          this.toggleInput();
          this.toggleButton();
        }}
        onChangeText={this.props.onChangeText} 
        onContentSizeChange={event => {
          const { contentSize } = event.nativeEvent;
          this.setState({
            height: contentSize.height
          });
        }}
        value={this.state.value}
      />
40?this.state.height:40}
]}
ref=“inputFlat”
onFocus={()=>{
this.toggleInput();
this.toggleButton();
}}
multiline={this.props.multiline}
onBlur={()=>{
this.toggleInput();
this.toggleButton();
}}
onChangeText={this.props.onChangeText}
onContentSizeChange={event=>{
const{contentSize}=event.nativeEvent;
这是我的国家({
高度:contentSize.height
});
}}
value={this.state.value}
/>

如果由于某种原因,在查看此答案时它似乎已损坏,请参阅文档以获取任何更新

,如果有人想要一个简单的解决方案,请使用新的v