当具有React Native的输入附件时如何滚动到焦点上的文本输入

ale*_*ngn 2 javascript reactjs react-native react-native-ios

我正在使用React Native应用程序,并且许多屏幕都有带有文本输入字段的表单。

当我按文本​​输入时,键盘将打开。我创建了一个浮动InputAccessory组件,该组件出现在键盘顶部以将其关闭,并带有“完成”按钮。

但是,现在有了此配件,当我单击输入字段或按键盘上的“下一步”按钮转到下一个字段时,ScrollView滚动条将文本输入的底部与键盘的顶部对齐。有了这个浮动附件,就会出现问题,如下所示,由于有了该附件,您看不到文本输入的内容,我想让scrollview多滚动一点以显示整个文本输入。

在此处输入图片说明

我可能可以为此进行计算并.scrollTo()ScrollView组件运行方法,但是这种模式在我的整个应用程序中非常常见,我正在寻找一种优雅的解决方案,该解决方案每次导入文本输入并专注于每次时都足够通用它。

你有什么建议吗?

谢谢

Amr*_*bib 5

我之前遇到过同样的问题,并且我有2个不同的解决方案,它们都为我工作。

1-使用react-native-keyboard-aware-scroll-view,请注意,该库将已经包含scrollView,因此您可以删除自己的滚动视图并使用

<KeyboardAwareScrollView>
  <View>
    <TextInput />
  </View>
</KeyboardAwareScrollView>
Run Code Online (Sandbox Code Playgroud)

您也可以查看文档以获取更多信息。

这种解决方案比较容易,因为您不需要自己处理任何事情,但是我想如果要包含scrollView在其中,将会遇到一些问题。


2-我曾经创建了一个组件AvoidKeyboard,该组件实际上可以执行与您的解决方案相似的操作,但是它过去一直使用键盘高度值来转换整个视图的顶部,因此该解决方案对我来说也非常有效。

实作

import React, { Component } from 'react';
import { Animated, Easing, Keyboard } from 'react-native';
import PropTypes from 'prop-types';


class AvoidKeyboard extends Component {
  constructor(props) {
    super(props);
    this.state = {
      animatedViewHeight: new Animated.Value(0),
      viewHeight: 0,
    };

    this.setViewHeightOnce = this.setViewHeightOnce.bind(this);
    this.keyboardWillShow = this.keyboardWillShow.bind(this);
    this.keyboardWillHide = this.keyboardWillHide.bind(this);
    this.keyboardDidShowListener = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow);
    this.keyboardDidHideListener = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide);
  }

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

  setViewHeightOnce(event) {
    const { height } = event.nativeEvent.layout;
    if (this.state.viewHeight === 0) {
      const avoidPaddingBottom = 15;
      this.setState({
        viewHeight: height + avoidPaddingBottom,
        animatedViewHeight: new Animated.Value(height + avoidPaddingBottom),
      });
    }
  }

  keyboardWillShow(e) {
    const { viewHeight } = this.state;
    if (viewHeight) {
      requestAnimationFrame(() => { // eslint-disable-line no-undef
        Animated.timing(this.state.animatedViewHeight, {
          toValue: (viewHeight - e.endCoordinates.height),
          duration: 200,
          delay: 0,
          easing: Easing.inOut(Easing.ease),
        }).start();
      });
    }
  }

  keyboardWillHide() {
    requestAnimationFrame(() => { // eslint-disable-line no-undef
      Animated.timing(this.state.animatedViewHeight, {
        toValue: this.state.viewHeight,
        duration: 200,
        delay: 0,
        easing: Easing.inOut(Easing.ease),
      }).start();
    });
  }

  render() {
    let animatedHeight;
    const { viewHeight } = this.state;
    if (viewHeight > 0) {
      animatedHeight = { maxHeight: this.state.animatedViewHeight };
    }
    return (
      <Animated.View
        style={[{ flex: 1, justifyContent: 'flex-end' }, animatedHeight]}
        onLayout={this.setViewHeightOnce}
      >
        {this.props.children}
      </Animated.View>
    );
  }
}


AvoidKeyboard.propTypes = {
  children: PropTypes.node.isRequired,
};


export default AvoidKeyboard;
Run Code Online (Sandbox Code Playgroud)

现在,您只需要将组件或屏幕包裹在其中AvoidKeyboard,打开键盘后,屏幕高度就会缩小,并且可以滚动屏幕


小智 5

我在 IOS 中遇到了很多键盘问题。没有 KeyboardSpacer、react-native-keyboard-aware-scroll-view 和更多包解决了这个问题。

最近我发现了react-native-keyboard-manager,它不需要一行代码就解决了我的所有问题,也包括模态等(我与作者没有任何关系,但这个包拯救了我)。给它一个改变。


ale*_*ngn 2

我找到了一个不涉及动画更改的解决方案。

当键盘打开时,我决定在 ScrollView 的底部添加一些边距,该边距对应于 InputAccessory 的高度。然后,当键盘关闭时,我会删除该边距。它看起来像这样:

import KeyboardListener from 'react-native-keyboard-listener';

...
render() [
  <ScrollView 
    key={1} 
    style={{ marginBottom: this.state.scrollViewMarginBottom }} 
  />,
  <InputAccessory key={2} onLayout={...} />,
  <KeyboardListener
    key={3}
    onWillShow={() => this.setState({ scrollViewMarginBottom: inputAccessoryHeight });
    onWillHide={() => this.setState({ scrollViewMarginBottom: 0 })
  />
]
Run Code Online (Sandbox Code Playgroud)