react-native - instalar - react native example
¿Cómo deslizar automáticamente la ventana desde detrás del teclado cuando TextInput tiene el foco? (14)
@Stephen
Si no le importa no animar la altura exactamente a la misma velocidad que aparece el teclado, puede usar LayoutAnimation, para que al menos la altura no salte a su lugar. p.ej
importe LayoutAnimation desde react-native y agregue los siguientes métodos a su componente.
getInitialState: function() {
return {keyboardSpace: 0};
},
updateKeyboardSpace: function(frames) {
LayoutAnimation.configureNext(animations.layout.spring);
this.setState({keyboardSpace: frames.end.height});
},
resetKeyboardSpace: function() {
LayoutAnimation.configureNext(animations.layout.spring);
this.setState({keyboardSpace: 0});
},
componentDidMount: function() {
KeyboardEventEmitter.on(KeyboardEvents.KeyboardDidShowEvent, this.updateKeyboardSpace);
KeyboardEventEmitter.on(KeyboardEvents.KeyboardWillHideEvent, this.resetKeyboardSpace);
},
componentWillUnmount: function() {
KeyboardEventEmitter.off(KeyboardEvents.KeyboardDidShowEvent, this.updateKeyboardSpace);
KeyboardEventEmitter.off(KeyboardEvents.KeyboardWillHideEvent, this.resetKeyboardSpace);
},
Algunos ejemplos de animaciones son (estoy usando el de primavera anterior):
var animations = {
layout: {
spring: {
duration: 400,
create: {
duration: 300,
type: LayoutAnimation.Types.easeInEaseOut,
property: LayoutAnimation.Properties.opacity,
},
update: {
type: LayoutAnimation.Types.spring,
springDamping: 400,
},
},
easeInEaseOut: {
duration: 400,
create: {
type: LayoutAnimation.Types.easeInEaseOut,
property: LayoutAnimation.Properties.scaleXY,
},
update: {
type: LayoutAnimation.Types.easeInEaseOut,
},
},
},
};
ACTUALIZAR:
Vea la respuesta de @ sherlock a continuación, a partir de react-native 0.11, el cambio de tamaño del teclado se puede resolver utilizando la funcionalidad integrada.
He visto este truco para que las aplicaciones nativas desplacen automáticamente la ventana, pero me pregunto la mejor manera de hacerlo para reaccionar nativo ... Cuando un campo se enfoca y se coloca bajo en la vista, el teclado cubrirá el campo de texto . Puede ver este problema en la vista de ejemplo TextInputExample.js de UIExplorer. ¿Alguien tiene una buena solución?
Combinamos parte del código de react-native-keyboard-spacer y el código de @Sherlock para crear un componente KeyboardHandler que se puede envolver alrededor de cualquier vista con elementos TextInput. ¡Funciona de maravilla! :-)
/**
* Handle resizing enclosed View and scrolling to input
* Usage:
* <KeyboardHandler ref=''kh'' offset={50}>
* <View>
* ...
* <TextInput ref=''username''
* onFocus={()=>this.refs.kh.inputFocused(this,''username'')}/>
* ...
* </View>
* </KeyboardHandler>
*
* offset is optional and defaults to 34
* Any other specified props will be passed on to ScrollView
*/
''use strict'';
var React=require(''react-native'');
var {
ScrollView,
View,
DeviceEventEmitter,
}=React;
var myprops={
offset:34,
}
var KeyboardHandler=React.createClass({
propTypes:{
offset: React.PropTypes.number,
},
getDefaultProps(){
return myprops;
},
getInitialState(){
DeviceEventEmitter.addListener(''keyboardDidShow'',(frames)=>{
if (!frames.endCoordinates) return;
this.setState({keyboardSpace: frames.endCoordinates.height});
});
DeviceEventEmitter.addListener(''keyboardWillHide'',(frames)=>{
this.setState({keyboardSpace:0});
});
this.scrollviewProps={
automaticallyAdjustContentInsets:true,
scrollEventThrottle:200,
};
// pass on any props we don''t own to ScrollView
Object.keys(this.props).filter((n)=>{return n!=''children''})
.forEach((e)=>{if(!myprops[e])this.scrollviewProps[e]=this.props[e]});
return {
keyboardSpace:0,
};
},
render(){
return (
<ScrollView ref=''scrollView'' {...this.scrollviewProps}>
{this.props.children}
<View style={{height:this.state.keyboardSpace}}></View>
</ScrollView>
);
},
inputFocused(_this,refName){
setTimeout(()=>{
let scrollResponder=this.refs.scrollView.getScrollResponder();
scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
React.findNodeHandle(_this.refs[refName]),
this.props.offset, //additionalOffset
true
);
}, 50);
}
}) // KeyboardHandler
module.exports=KeyboardHandler;
Estoy usando un método más simple, pero aún no está animado. Tengo un estado de componente llamado "bumpedUp", que por defecto es 0, pero se establece en 1 cuando el textInput se enfoca, así:
En mi entrada de texto:
onFocus={() => this.setState({bumpedUp: 1})}
onEndEditing={() => this.setState({bumpedUp: 0})}
También tengo un estilo que le da al contenedor de envoltura de todo en esa pantalla un margen inferior y un margen superior negativo, como este:
mythingscontainer: {
flex: 1,
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
},
bumpedcontainer: {
marginBottom: 210,
marginTop: -210,
},
Y luego, en el contenedor de envoltura, configuro los estilos de esta manera:
<View style={[styles.mythingscontainer, this.state.bumpedUp && styles.bumpedcontainer]}>
Entonces, cuando el estado "bumpedUp" se establece en 1, el estilo bumpedcontainer se activa y mueve el contenido hacia arriba.
Un poco hacky y los márgenes están codificados, pero funciona :)
Facebook
Open Source
KeyboardAvoidingView
en reaccionar nativo 0.29 para resolver este problema.
La documentación y el ejemplo de uso se pueden encontrar
here
.
Primero necesitas instalar react-native-keyboardevents .
- En XCode, en el navegador del proyecto, haga clic con el botón derecho en Bibliotecas ➜ Agregar archivos a [nombre de su proyecto] Vaya a node_modules ➜ react-native-keyboardevents y agregue el archivo .xcodeproj
- En XCode, en el navegador de proyectos, seleccione su proyecto. Agregue lib * .a del proyecto keyboardevents a las Fases de compilación de su proyecto ➜ Enlace binario con bibliotecas Haga clic en el archivo .xcodeproj que agregó antes en el navegador del proyecto y vaya a la pestaña Configuración de compilación. Asegúrese de que ''Todos'' esté activado (en lugar de ''Básico''). Busque las rutas de búsqueda de encabezado y asegúrese de que contenga $ (SRCROOT) /../ react-native / React y $ (SRCROOT) /../../ React: marque ambos como recursivos.
- Ejecute su proyecto (Cmd + R)
Luego de vuelta en javascript land:
Debe importar los eventos react-native-keyboar.
var KeyboardEvents = require(''react-native-keyboardevents'');
var KeyboardEventEmitter = KeyboardEvents.Emitter;
Luego, en su vista, agregue algún estado para el espacio del teclado y actualice al escuchar los eventos del teclado.
getInitialState: function() {
KeyboardEventEmitter.on(KeyboardEvents.KeyboardDidShowEvent, (frames) => {
this.setState({keyboardSpace: frames.end.height});
});
KeyboardEventEmitter.on(KeyboardEvents.KeyboardWillHideEvent, (frames) => {
this.setState({keyboardSpace: 0});
});
return {
keyboardSpace: 0,
};
},
Finalmente, agregue un espaciador a su función de renderizado debajo de todo para que cuando aumente el tamaño aumente sus cosas.
<View style={{height: this.state.keyboardSpace}}></View>
También es posible usar la API de animación, pero por simplicidad, solo ajustamos después de la animación.
Prueba esto:
import React, {
DeviceEventEmitter,
Dimensions
} from ''react-native'';
...
getInitialState: function() {
return {
visibleHeight: Dimensions.get(''window'').height
}
},
...
componentDidMount: function() {
let self = this;
DeviceEventEmitter.addListener(''keyboardWillShow'', function(e: Event) {
self.keyboardWillShow(e);
});
DeviceEventEmitter.addListener(''keyboardWillHide'', function(e: Event) {
self.keyboardWillHide(e);
});
}
...
keyboardWillShow (e) {
let newSize = Dimensions.get(''window'').height - e.endCoordinates.height;
this.setState({visibleHeight: newSize});
},
keyboardWillHide (e) {
this.setState({visibleHeight: Dimensions.get(''window'').height});
},
...
render: function() {
return (<View style={{height: this.state.visibleHeight}}>your view code here...</View>);
}
...
A mi me funciono. Básicamente, la vista se reduce cuando se muestra el teclado y vuelve a crecer cuando está oculto.
Puede combinar algunos de los métodos en algo un poco más simple.
Adjunte un oyente onFocus en sus entradas
<TextInput ref="password" secureTextEntry={true}
onFocus={this.scrolldown.bind(this,''password'')}
/>
Nuestro método de desplazamiento hacia abajo se parece a:
scrolldown(ref) {
const self = this;
this.refs[ref].measure((ox, oy, width, height, px, py) => {
self.refs.scrollView.scrollTo({y: oy - 200});
});
}
Esto le dice a nuestra vista de desplazamiento (recuerde agregar una referencia) para desplazarse hacia abajo a la posición de nuestra entrada enfocada - 200 (es aproximadamente el tamaño del teclado)
componentWillMount() {
this.keyboardDidHideListener = Keyboard.addListener(
''keyboardWillHide'',
this.keyboardDidHide.bind(this)
)
}
componentWillUnmount() {
this.keyboardDidHideListener.remove()
}
keyboardDidHide(e) {
this.refs.scrollView.scrollTo({y: 0});
}
Aquí restablecemos nuestra vista de desplazamiento hacia arriba,
Quizás sea IQKeyboardManager tarde, pero la mejor solución es usar una biblioteca nativa, IQKeyboardManager
Simplemente arrastre y suelte el directorio IQKeyboardManager del proyecto de demostración a su proyecto de iOS. Eso es. También puede configurar algunos valus, como isToolbar habilitado, o el espacio entre la entrada de texto y el teclado en el archivo AppDelegate.m. Más detalles sobre la personalización se encuentran en el enlace de la página de GitHub que he agregado.
Solo quería mencionar, ahora hay un
KeyboardAvoidingView
en RN.
Solo impórtelo y úselo como cualquier otro módulo en RN.
Aquí está el enlace al commit en RN:
https://github.com/facebook/react-native/commit/8b78846a9501ef9c5ce9d1e18ee104bfae76af2e
Está disponible desde 0.29.0
También han incluido un ejemplo en UIExplorer.
También me encuentro con esta pregunta. Finalmente, lo resuelvo definiendo la altura de cada escena, como:
<Navigator ... sceneStyle={{height: **}} />
Y también utilizo un módulo de terceros https://github.com/jaysoo/react-native-extra-dimensions-android para obtener la altura real.
Usé TextInput.onFocus y ScrollView.scrollTo.
...
<ScrollView ref="scrollView">
...
<TextInput onFocus={this.scrolldown}>
...
scrolldown: function(){
this.refs.scrollView.scrollTo(width*2/3);
},
Utilizo la respuesta brysgo para subir la parte inferior de mi vista de desplazamiento. Luego uso el onScroll para actualizar la posición actual de la vista de desplazamiento. Luego encontré este React Native: obtener la posición de un elemento para obtener la posición de la entrada de texto. Luego hago algunos cálculos matemáticos simples para determinar si la entrada está en la vista actual. Luego uso scrollTo para mover la cantidad mínima más un margen. Es muy suave Aquí está el código para la parte de desplazamiento:
focusOn: function(target) {
return () => {
var handle = React.findNodeHandle(this.refs[target]);
UIManager.measureLayoutRelativeToParent( handle,
(e) => {console.error(e)},
(x,y,w,h) => {
var offs = this.scrollPosition + 250;
var subHeaderHeight = (Sizes.width > 320) ? Sizes.height * 0.067 : Sizes.height * 0.077;
var headerHeight = Sizes.height / 9;
var largeSpace = (Sizes.height - (subHeaderHeight + headerHeight));
var shortSpace = largeSpace - this.keyboardOffset;
if(y+h >= this.scrollPosition + shortSpace) {
this.refs.sv.scrollTo(y+h - shortSpace + 20);
}
if(y < this.scrollPosition) this.refs.sv.scrollTo(this.scrollPosition - (this.scrollPosition-y) - 20 );
}
);
};
},
react-native-keyboard-aware-scroll-view me resolvió el problema. react-native-keyboard-aware-scroll-view en GitHub
Respuesta 2017
El
KeyboardAvoidingView
es probablemente la mejor manera de hacerlo ahora.
Mira los documentos
here
.
Es realmente simple en comparación con el módulo de
Keyboard
que le da al desarrollador más control para realizar animaciones.
Spencer Carli
demostró todas las formas posibles en
su blog mediano
.
Respuesta 2015
La forma correcta de hacer esto en
react-native
no requiere bibliotecas externas, aprovecha el código nativo e incluye animaciones.
Primero defina una función que manejará el evento
onFocus
para cada
TextInput
(o cualquier otro componente al que le gustaría desplazarse):
// Scroll a component into view. Just pass the component ref string.
inputFocused (refName) {
setTimeout(() => {
let scrollResponder = this.refs.scrollView.getScrollResponder();
scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
React.findNodeHandle(this.refs[refName]),
110, //additionalOffset
true
);
}, 50);
}
Luego, en su función de renderizado:
render () {
return (
<ScrollView ref=''scrollView''>
<TextInput ref=''username''
onFocus={this.inputFocused.bind(this, ''username'')}
</ScrollView>
)
}
Esto usa el
RCTDeviceEventEmitter
para eventos y
RCTDeviceEventEmitter
de teclado, mide la posición del componente usando
RCTUIManager.measureLayout
y calcula el movimiento exacto de desplazamiento requerido en
scrollResponderInputMeasureAndScrollToKeyboard
.
Es posible que desee jugar con el parámetro
additionalOffset
Offset, para adaptarse a las necesidades de su diseño de interfaz de usuario específico.