haciendo una línea múltiple, expandiendo TextInput con React-Native

Estoy trabajando en una aplicación nativa de reacción y necesito una input de text que tenga una funcionalidad similar a la vista de text en la aplicación de "posts" en iOS: debería comenzar como una línea y luego expandirse con gracia hasta más líneas hasta algún límite (como 5 líneas de text) y luego comienza a desplazarse a la última línea según sea necesario.

SlackTextViewController un vistazo al SlackTextViewController pero a) parece que tiene muchas cosas que no quiero yb) Me gustaría tratar de mantener tanto código en React (y fuera del objective-C / swift) como posible.

Edit: Solo quiero enfatizar que preferiría el código REACT (JAVASCRIPT), como se mencionó anteriormente, en lugar de Objective-C o Swift.

Probé dos forms diferentes de hacer esto hoy. Tampoco son los mejores, pero pensé registrar mis esfuerzos en caso de que sean útiles. Ambos definitivamente tuvieron el efecto que estás buscando, aunque en algún momento se demoraron con toda la comunicación asincrónica.

1) Altura del text fuera de pantalla

Así que justo debajo de TextInput, agregué un campo de text normal con la misma fuente y relleno y tal. onChange escucha onChange en la input y llamé setState({text: event.nativeEvent.text}) . El text presentado obtuvo su valor del estado. Ambos tenían onLayout Oyentes. Básicamente, el objective era get la altura de TextInput del text (sin restricciones). Luego oculté la manera de text fuera de pantalla

https://gist.github.com/bleonard/f7d748e89ad2a485ec34

2) Módulo nativo

Realmente, solo necesitaba la altura del contenido en el UITextView real . Entonces agregué una categoría a RCTUIManager ya que hay varios methods que ya son útiles. Me deshice de la vista de text oculta. Entonces, onChange , pido la altura y uso eso de la misma manera a través del estado.

https://gist.github.com/bleonard/6770fbfe0394a34c864b

3) Github PR

Lo que realmente espero es que esta RP sea aceptada. Parece hacer algo así automáticamente.

https://github.com/facebook/react-native/pull/1229

Agregar multiline={true} a una input de text permitirá desplazarse si la cantidad de text supera el espacio disponible. A continuación, puede cambiar la altura de TextInput accediendo a nativeEvent.contentSize.height del evento desde el accesorio onChange.

 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} /> ); } } 

Implementar el método delegado de UITextView textViewDidChange y jugar con el rectángulo

 - (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; } 

A partir de octubre de 17 hay un buen componente de Wix para hacer esto:

https://github.com/wix/react-native-autogrow-textinput

El uso puede ser muy simple:

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

Y hay algunos accesorios adicionales como maxHeight y maxHeight por ejemplo.

Lo estoy usando en RN 0.47.2