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

标签 javascript reactjs react-native react-native-ios

我正在开发一个 React Native 应用程序,许多屏幕都有带有文本输入字段的表单。

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

但是现在我有了这个配件,当我单击输入字段或按键盘上的“下一步”按钮转到下一个字段时,ScrollView 滚动以对齐输入字段的底部使用键盘顶部的文本输入。使用这个 float 附件会带来问题,如下所示,由于该附件,您无法看到文本输入的内容,并且我想让 ScrollView 滚动更多一点以显示整个文本输入。

enter image description here

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

你有什么建议吗?

谢谢

最佳答案

我之前遇到过同样的问题,我有两种不同的解决方案,它们都适合我。

1- 使用 react-native-keyboard-aware-scroll-view ,请注意,该库已经包含scrollView,因此您删除自己的 ScrollView 并使用

<KeyboardAwareScrollView>
  <View>
    <TextInput />
  </View>
</KeyboardAwareScrollView>

您还可以查看documentation了解更多信息。

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

<小时/>

2-我曾经创建了一个组件AvoidKeyboard,它实际上执行与您的解决方案类似的操作,但它用于使用键盘高度值将整个 View 转换为顶部,这个解决方案也非常适合我。

实现

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;

现在,您只需将组件或屏幕包裹在 AvoidKeyboard 内,一旦键盘打开,屏幕高度就会缩小,并且您将能够滚动屏幕

关于javascript - 当有 React Native 输入附件时如何滚动到焦点上的文本输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47350254/

相关文章:

react-native - react native : Unable to resolve module ./CameraRollView

javascript - 使用 CanvasJs 在图表的任何部分添加文本

javascript - array.shift() 在 axios 响应中不起作用?

javascript - 如何在react变量中获取onChange的输入值?

javascript - 在 react native 应用程序中保留 Firebase 数据

android - ScrollView : How to reproduce snapToInterval and snapToAlignment for Android?

c# - 如何在javascript中获取动态控件的id

javascript - appendTo 自定义元素未使用自动完成功能进行更新

javascript - jquery 在表单中选择 div 类并添加值

reactjs - 在@auth0 中 Jest 模拟 Auth0Client