【问题标题】:How to scroll to text input on focus when there is an input accessory with React Native当有 React Native 的输入附件时如何滚动到焦点上的文本输入
【发布时间】:2020-06-20 04:08:37
【问题描述】:

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

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

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

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

你有什么建议吗?

谢谢

【问题讨论】:

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


    【解决方案1】:

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

    1- 使用 react-native-keyboard-aware-scroll-view ,注意这个库已经包含 scrollView 所以你删除你自己的滚动视图并使用

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

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

    这个解决方案更容易,因为你不需要自己处理任何事情,但我认为如果你想在其中包含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;
    

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

    【讨论】:

    • 我刚试了一下KeyboardAwareScrollView,这个东西看起来很hacky,动画不完美,回到原来的位置很奇怪。我很难过:(
    • 您是否尝试过第二种解决方案? ,动画在第二种解决方案中更好
    • 我在这里添加了AvoidKeyboard 组件的实现,希望对您有所帮助
    【解决方案2】:

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

    最近我发现了 react-native-keyboard-manager ,它无需一行代码就解决了我所有的问题,也包括模态等等(我与作者无关,但这个包为我节省了一天)。给它一个改变。

    【讨论】:

    • 该死的......这就像魔法一样!我会完全去看看它是如何完成的。谢谢!
    【解决方案3】:

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

    当键盘打开时,我决定在 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 })
      />
    ]
    

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题,网上阅读我想出了以下解决方案

      适用于安卓

      转到您的AndroidManifest.xml 并添加android:windowSoftInputMode="adjustPan"

      <activity
              android:name=".MainActivity"
              android:windowSoftInputMode="adjustPan">
              .....
      </activity>
      

      IOS

      只需按照此 repo 中的说明进行操作即可。 https://github.com/douglasjunior/react-native-keyboard-manager.

      希望这会有所帮助。 :)

      【讨论】:

      • 库建议使用“adjustResize”而不是“adjustPan”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-11
      • 1970-01-01
      • 2019-07-04
      • 2023-03-17
      • 2019-09-27
      • 2017-02-06
      相关资源
      最近更新 更多