Reactjs 在scrollview中,React Native需要两次点击来更改输入焦点

Reactjs 在scrollview中,React Native需要两次点击来更改输入焦点,reactjs,keyboard,react-native,Reactjs,Keyboard,React Native,想象一下,简单的ScrollView具有多个文本输入,如 <ScrollView style={styles.container}> <TextInput style={styles.input} /> <TextInput style={styles.input} /> </ScrollView> 当我输入第一个输入时,键盘打开,我可以输入文本。当我想切换到第二次输入时,我需要轻触两下-第一次输入关闭键盘,第二次轻触

想象一下,简单的ScrollView具有多个文本输入,如

  <ScrollView style={styles.container}>
    <TextInput style={styles.input} />
    <TextInput style={styles.input} />
  </ScrollView>

当我输入第一个输入时,键盘打开,我可以输入文本。当我想切换到第二次输入时,我需要轻触两下-第一次输入关闭键盘,第二次轻触打开键盘进行第二次输入

一种解决方案是使用
键盘shoulldPersistTaps={true}
-切换工作正常,但此时键盘根本没有关闭,键盘可以覆盖一些后续输入(或按钮)。 我也可以使用
keyboardismissmode
,但只需在拖动时关闭键盘即可

我的问题是,当我点击另一个输入时,焦点会立即改变,而不会重新打开键盘,当我点击其他地方时,键盘会关闭,如何将这两种行为结合到最佳用户体验中

我使用的是RN0.22,示例应用程序可在


更新-此问题可能已在RN 0.40中解决-请参阅

这并不是您想要的,但当文本输入具有焦点时,将自动从键盘后面滑出窗口;解决键盘的问题可以解决以后的一些输入(或按钮)问题。

最后,我发现解决方案不是最优的(从编码角度),但从用户角度来看是可行的。我制作了一个小组件,可以用来代替
ScrollView

export class InputScrollView extends React.Component {

  constructor(props, ctx) {
      super(props, ctx);
      this.handleCapture = this.handleCapture.bind(this);
  }

  render() {
    return (
      <ScrollView keyboardShouldPersistTaps={true} keyboardDismissMode='on-drag'>
        <View onStartShouldSetResponderCapture={this.handleCapture}>
          {this.props.children}
        </View>
      </ScrollView>
    );
  }

  handleCapture(e) {
    const focusField = TextInputState.currentlyFocusedField();
    const target = e.nativeEvent.target;
    if (focusField != null && target != focusField){
      const inputs = this.props.inputs;
      if (inputs && inputs.indexOf(target) === -1) {
        dismissKeyboard();
      }
    }
  }
}

InputScrollView.propTypes = {
  inputs : React.PropTypes.array,
}
导出类InputScrollView扩展了React.Component{ 建造师(道具、ctx){ 超级(道具,ctx); this.handleCapture=this.handleCapture.bind(this); } render(){ 返回( {this.props.children} ); } 手拍(e){ const focusField=TextInputState.currentlyFocusedField(); const target=e.nativeEvent.target; if(focusField!=null&&target!=focusField){ 常量输入=this.props.inputs; if(输入和输入.indexOf(目标)=-1){ 不使用键盘(); } } } } InputScrollView.propTypes={ 输入:React.PropTypes.array, }
唯一的缺点是我需要“手动”收集所有文本输入的节点句柄(由React.findNodeHandle返回),并将其作为数组传递给组件。

我用这段代码解决了我的问题

<ScrollView
   keyboardDismissMode='on-drag'
   keyboardShouldPersistTaps={true}
>

我更新了上述答案,因为keyboardShouldPersistTaps={true}已被弃用,现在使用keyboardShouldPersistTaps='always'

export class InputScrollView extends React.Component {

  constructor(props, ctx) {
      super(props, ctx);
      this.handleCapture = this.handleCapture.bind(this);
  }

  render() {
    return (
      <ScrollView keyboardShouldPersistTaps='always' keyboardDismissMode='on-drag'>
        <View onStartShouldSetResponderCapture={this.handleCapture}>
          {this.props.children}
        </View>
      </ScrollView>
    );
  }

  handleCapture(e) {
    const focusField = TextInputState.currentlyFocusedField();
    const target = e.nativeEvent.target;
    if (focusField != null && target != focusField){
      const inputs = this.props.inputs;
      if (inputs && inputs.indexOf(target) === -1) {
        dismissKeyboard();
      }
    }
  }
}

InputScrollView.propTypes = {
  inputs : React.PropTypes.array,
}
导出类InputScrollView扩展了React.Component{ 建造师(道具、ctx){ 超级(道具,ctx); this.handleCapture=this.handleCapture.bind(this); } render(){ 返回( {this.props.children} ); } 手拍(e){ const focusField=TextInputState.currentlyFocusedField(); const target=e.nativeEvent.target; if(focusField!=null&&target!=focusField){ 常量输入=this.props.inputs; if(输入和输入.indexOf(目标)=-1){ 不使用键盘(); } } } } InputScrollView.propTypes={ 输入:React.PropTypes.array, } 通过查看,我找到了一种可以执行以下操作的方法:

  • 在文本Input1中输入后,如果单击Input2,键盘将保持不变
  • 如果你点击某个空的地方,键盘会自动消失
  • 代码如下:

    <ScrollView
      keyboardDismissMode="none"
      keyboardShouldPersistTaps="handled"
    >
      {content}
    </ScrollView>
    
    
    {content}
    
    在新的react本机版本中,您可以保留滚动视图点击事件,如下所示:

    <ScrollView
          keyboardShouldPersistTaps='always'
          keyboardDismissMode={'interactive'}></ScrollView>
    
    
    

    主要诀窍是
    键盘应该是PersistTaps='always'

    谢谢。若你们点击“输入”按钮,那个么这个答案会有帮助,一旦键盘打开,它就会被键盘覆盖。但是,如果第二个输入(或按钮)已被覆盖,则不会对您有所帮助-因为此技巧只会将第一个点击的输入滚动到“视图”中但是对于其他组件没有任何保证。问题是,当您只需点击输入外部时,键盘没有关闭。@sodik看看我的ans:)您能解释一下
    TextInputState
    来自哪里吗?哪个软件包?它带有RN-see-我确实像从“TextInputState”导入TextInputState一样导入了它谢谢,我来看看@索迪克