在iOS上滚动时阻止TextInput聚焦

rud*_*vac 7 ios react-native

我有一个ScrollViewTextInput multiline={true}从状态下读取其用作与动态高度的文本区域字段和内容(它有一个Text在其内部显示文本字段).

我的问题是,当TextInput增长到几行时,如果我通过在该字段上滑动来滚动屏幕(我不长按或类似的东西),该字段将触发其onFocus事件并且键盘将显示.

它不会每次都发生,但它发生的时间足以使它变得非常烦人.

我试着设置ScrollViewkeyboardDismissMode="on-drag",但它并没有帮助,键盘仍然显示,而视图滚动.

<ScrollView keyboardDismissMode="on-drag">
  <TextInput multiline={true} onFocus={() => console.log('boop')}>
    <Text>{this.state.someText}</Text>
  </TextInput>
</ScrollView>
Run Code Online (Sandbox Code Playgroud)

我也尝试过在没有内Text场的情况下进行,TextInput并且onFocus仍然会激活.

难道我做错了什么?还有什么我可以尝试的,比如检查屏幕是否仍在滚动以及blur()字段是否true或类似的东西?

如果我明确地点击它,我有什么办法可以专注于这个领域吗?

谢谢你的帮助.

Map*_*psy 7

这是一个hacky解决方法:

将您的包裹TextInput在 a 中TouchableOpacity,并将TextInputpointerEventsprop设置为指向一个状态变量,即this.state.pointerEvents,并将该变量初始化为'none'。这会阻止TextInput接收任何触摸事件,并让您在不捕获焦点的情况下滑动它的顶部。

在 的onPress道具中TouchableOpacitypointerEvents通过将状态变量设置为 来启用'auto',然后使用对 的引用手动分配焦点TextInput,即:

this._textInput.focus()

最后,覆盖onBlur你的propTextInput并让它重新初始化pointerEvents状态,'none'这样在用户完成编辑后它的行为就像之前一样。

解释

其工作方式是,TouchableOpacity本质上捕获通常由 消耗的所有触摸事件TextInput,但以我们期望的友好方式与沿 UI 其余部分的拖动进行交互。当onPress为 触发事件时TouchableOpacity,我们实际上是在谈论真正的新闻事件,而不是误认的拖拽事件。

如果您不想使用TouchableOpacity的动画,您可以将activeOpacity道具分配给1,或者使用 aTouchableWithoutFeedback代替。


Pal*_*and 1

更新

在 0.54.2 中再次工作!

您应该有条件地在 Android 上排除此代码(如下所示),因为现在 React Native 似乎已经处理了此问题。


更新

在 0.49.0 中不再有效


用适当TextInput的. 这是一个可以做到这一点的组件:ViewpanHandlers

import React, {Component} from 'react';
import {Platform, PanResponder, View, TextInput as RNTextInput} from 'react-native';

class TextInput extends Component<Props> {

  componentWillMount() {
    if (Platform.OS === 'ios') {
      this.panResponder = PanResponder.create({
        onStartShouldSetPanResponderCapture: () => true,
      });
    }
  }

  render() {
    <View {...Platform.OS === 'ios' ? this.panResponder.panHandlers : {}}>
      <RNTextInput {...this.props} />
    </View>
  }
}
Run Code Online (Sandbox Code Playgroud)

在 RN 0.46.1 中测试。