简体   繁体   English

React-native 如何在 textinput 上向上移动屏幕

[英]React-native how to move screen up on textinput

I have a login screen created using react-native.我有一个使用 react-native 创建的登录屏幕。

How can I shift my screen up when the user is typing in the textInput?当用户在 textInput 中输入时,如何将我的屏幕向上移动?

Do I listen to the onFocus() event and use css styling to change the style of the view?我是否监听 onFocus() 事件并使用 css 样式来更改视图的样式?

在 2017 (RN 0.43) 中有一个特殊的组件: KeyboardAvoidingView

You can use ScrollView to control screen up and down movements.您可以使用ScrollView来控制屏幕的上下移动。 As long as user hasn't focused any TextInput , you can disable scroll .只要用户没有关注任何TextInput ,您就可以禁用 scroll On focus, just shift up the scrollview using Content Offset prop.在焦点上,只需使用Content Offset道具向上移动滚动视图。

<TextInput
    onFocus={this.textInputFocused.bind(this)}
  />

textInputFocused() {
//do your stuff here. scroll screen up
}

Hope it helps!希望能帮助到你!

Night Fury's answer is pretty good, though wouldn't fuss with the ScrollView's contentOffset , I'd use the ScrollResponder : Night Fury 的回答非常好,虽然不会对 ScrollView 的contentOffset大惊小怪,但我会使用ScrollResponder

render() {
  return (
    <ScrollView ref="myScrollView">
      <TextInput
        ref="myInput"
        onFocus={this._scrollToInput.bind(this)}
      />
    </ScrollView>
  );
}

_scrollToInput {
  const scrollResponder = this.refs.myScrollView.getScrollResponder();
  const inputHandle = React.findNodeHandle(this.refs.myInput)

  scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
    inputHandle, // The TextInput node handle
    0, // The scroll view's bottom "contentInset" (default 0)
    true // Prevent negative scrolling
  );
}

See the method definition: scrollResponderScrollNativeHandleToKeyboard查看方法定义: scrollResponderScrollNativeHandleToKeyboard

import {KeyboardAvoidingView} from 'react-native';

<KeyboardAvoidingView style={styles.container} behavior="padding" enabled>

    <Text style={{height: 100, marginTop: 30}}> test text before input</Text>
    <Text style={{height: 100, marginTop: 30}}> test text before input</Text>
    <Text style={{height: 100, marginTop: 30}}> test text before input</Text>
    <Text style={{height: 100, marginTop: 30}}> test text before input</Text>
    <Text style={{height: 100, marginTop: 30}}> test text before input</Text>

    <TextInput
        style={{height: 40, borderColor: 'gray', borderWidth: 1}}
        onChangeText={(text) => this.setState({text})}
        value={this.state.text}
    />

    <Text style={{height: 100, marginTop: 20}}>1 test text after input</Text>
    <Text style={{height: 100, marginTop: 20}}>2 test text after input</Text>
    <Text style={{height: 100, marginTop: 20}}>3 test text after input</Text>
    <Text style={{height: 100, marginTop: 20}}>4 test text after input</Text>
    <Text style={{height: 100, marginTop: 20}}>5 test text after input</Text>

</KeyboardAvoidingView>

Run in snack : https://snack.expo.io/H1BE5ZoXV跑在小吃: https : //snack.expo.io/H1BE5ZoXV

这个做得很好,引入了一个 KeyboardAwareScrollView 组件,该组件向上滚动视图与键盘输入匹配,然后向下滚动。

And another solution, working with RN 0.2, this time instead of squashing the content it scrolls.另一个解决方案,使用 RN 0.2,这次不是压缩滚动的内容。

 inputFocused: function(ref) {
   this._scroll(ref, 75);
 },

 inputBlurred: function(ref) {
   this._scroll(ref, 0);
 },

 _scroll: function(ref, offset) {
   setTimeout(() => {
     var scrollResponder = this.refs.myScrollView.getScrollResponder();
     scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
                React.findNodeHandle(this.refs[ref]),
                offset,
                true
            );
     });
  },

... ...

render: function() {
  return <View style={{flex: 1}}> 
    <ScrollView ref="myScrollView" keyboardDismissMode='interactive' contentContainerStyle={{flex: 1}}>
      <TextInput
        ref="myInput"
        onFocus={this.inputFocused.bind(this, 'myInput')}
        onBlur={this.inputBlurred.bind(this, 'myInput')} />
    </ScrollView>
  </View>
}

It's a crap shoot to get the native keyboard awareness functionality of ScrollView working.让 ScrollView 的本机键盘感知功能正常工作是一个废话。 For my Android app, it works perfectly in one screen that is nearly identical as the other for which doesn't work.对于我的 Android 应用程序,它可以在一个屏幕上完美运行,而另一个屏幕几乎完全相同,而另一个屏幕则不起作用。 And on iOS, it just doesn't work.而在 iOS 上,它就是行不通。 This is what's working for me:这对我有用:

import { Keyboard, ScrollView, StyleSheet, View } from 'react-native';

this.state = {
    filler: false,
}

componentWillMount() {
    this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));
    this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
}

componentWillUnmount() {
    this.keyboardDidShowListener.remove();
    this.keyboardDidHideListener.remove();
}

_keyboardDidShow() {
    this.setState({filler: true})
    setTimeout(() => this.vertical && this.vertical.scrollToEnd({animated: true}), 0);
}

_keyboardDidHide() {
    this.setState({filler: false})
}


...
return (
  <ScrollView ref={ref => this.vertical = ref}>
    <TextInput/>
    { this.state.filler ? <View style={styles.filler}/> : null }
  </ScrollView>
)

styles.filler = {
    height: 'Keyboard Height'
}

Note: This might only work if your <TextInput/> is at the bottom of the screen which it was in my case.注意:这可能仅在您的<TextInput/>位于屏幕底部时才有效,就我而言。

Try to set multiline={true} prop for the TextInput. 尝试为TextInput设置multiline={true}属性。 It worked for me. 它为我工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM