[javascript] TextInput에 포커스가있을 때 키보드 뒤에서 창을 자동으로 슬라이드하는 방법은 무엇입니까?

네이티브 앱이 창을 자동으로 스크롤하는이 해킹을 보았지만 React Native에서 가장 좋은 방법이 궁금합니다. <TextInput>필드가 포커스를 받고 뷰에서 낮은 위치 에 놓이면 키보드가 텍스트 필드를 덮을 것입니다.

이 문제는 예제 UIExplorer의 TextInputExample.js보기 에서 볼 수 있습니다.

누구에게 좋은 해결책이 있습니까?



답변

2017 년 답변

KeyboardAvoidingView아마 지금 가야하는 가장 좋은 방법입니다. 여기 에서 문서를 확인 하십시오 . Keyboard개발자에게 애니메이션을 수행하는 데 더 많은 제어 권한을 부여 하는 모듈에 비해 정말 간단 합니다. Spencer Carli그의 매체 블로그 에서 가능한 모든 방법을 시연 했습니다 .

2015 년 답변

에서이 작업을 수행하는 올바른 방법 react-native은 외부 라이브러리가 필요하지 않고 네이티브 코드를 활용하며 애니메이션을 포함합니다.

먼저 onFocus각 이벤트를 처리 할 함수 TextInput(또는 스크롤하려는 다른 구성 요소)를 정의합니다.

// Scroll a component into view. Just pass the component ref string.
inputFocused (refName) {
  setTimeout(() => {
    let scrollResponder = this.refs.scrollView.getScrollResponder();
    scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
      React.findNodeHandle(this.refs[refName]),
      110, //additionalOffset
      true
    );
  }, 50);
}

그런 다음 렌더링 함수에서 :

render () {
  return (
    <ScrollView ref='scrollView'>
        <TextInput ref='username'
                   onFocus={this.inputFocused.bind(this, 'username')}
    </ScrollView>
  )
}

이것은 RCTDeviceEventEmitter키보드 이벤트 및 크기 조정을 위해를 사용 하고을 사용하여 구성 요소의 위치를 ​​측정하고 RCTUIManager.measureLayout에서 필요한 정확한 스크롤 이동을 계산합니다 scrollResponderInputMeasureAndScrollToKeyboard.

additionalOffset특정 UI 디자인의 요구 사항에 맞게 매개 변수 를 가지고 놀 수 있습니다 .


답변

이 문제를 해결하기 위해 반응 네이티브 0.29에서 오픈 소스 페이스 북 KeyboardAvoidingView. 문서 및 사용 예는 여기 에서 찾을 수 있습니다 .


답변

우리는 React-native-keyboard-spacer 코드 형태와 @Sherlock의 코드를 결합하여 TextInput 요소가있는 모든 뷰를 감싸는 KeyboardHandler 구성 요소를 만들었습니다. 매력처럼 작동합니다! 🙂

/**
 * Handle resizing enclosed View and scrolling to input
 * Usage:
 *    <KeyboardHandler ref='kh' offset={50}>
 *      <View>
 *        ...
 *        <TextInput ref='username'
 *          onFocus={()=>this.refs.kh.inputFocused(this,'username')}/>
 *        ...
 *      </View>
 *    </KeyboardHandler>
 *
 *  offset is optional and defaults to 34
 *  Any other specified props will be passed on to ScrollView
 */
'use strict';

var React=require('react-native');
var {
  ScrollView,
  View,
  DeviceEventEmitter,
}=React;


var myprops={
  offset:34,
}
var KeyboardHandler=React.createClass({
  propTypes:{
    offset: React.PropTypes.number,
  },
  getDefaultProps(){
    return myprops;
  },
  getInitialState(){
    DeviceEventEmitter.addListener('keyboardDidShow',(frames)=>{
      if (!frames.endCoordinates) return;
      this.setState({keyboardSpace: frames.endCoordinates.height});
    });
    DeviceEventEmitter.addListener('keyboardWillHide',(frames)=>{
      this.setState({keyboardSpace:0});
    });

    this.scrollviewProps={
      automaticallyAdjustContentInsets:true,
      scrollEventThrottle:200,
    };
    // pass on any props we don't own to ScrollView
    Object.keys(this.props).filter((n)=>{return n!='children'})
    .forEach((e)=>{if(!myprops[e])this.scrollviewProps[e]=this.props[e]});

    return {
      keyboardSpace:0,
    };
  },
  render(){
    return (
      <ScrollView ref='scrollView' {...this.scrollviewProps}>
        {this.props.children}
        <View style={{height:this.state.keyboardSpace}}></View>
      </ScrollView>
    );
  },
  inputFocused(_this,refName){
    setTimeout(()=>{
      let scrollResponder=this.refs.scrollView.getScrollResponder();
      scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
        React.findNodeHandle(_this.refs[refName]),
        this.props.offset, //additionalOffset
        true
      );
    }, 50);
  }
}) // KeyboardHandler

module.exports=KeyboardHandler;


답변

먼저 react-native-keyboardevents 를 설치해야합니다 .

  1. XCode의 프로젝트 탐색기에서 Libraries ➜ Add Files to [your project ‘s name]을 마우스 오른쪽 버튼으로 클릭하고 node_modules ➜ react-native-keyboardevents로 이동 한 다음 .xcodeproj 파일을 추가합니다.
  2. XCode의 프로젝트 탐색기에서 프로젝트를 선택합니다. keyboardevents 프로젝트의 lib * .a를 프로젝트의 빌드 단계에 추가합니다. ➜ 바이너리를 라이브러리와 연결하기 전에 프로젝트 탐색기에서 추가 한 .xcodeproj 파일을 클릭하고 빌드 설정 탭으로 이동합니다. ‘기본’대신 ‘모두’가 켜져 있는지 확인합니다. 헤더 검색 경로를 찾아서 $ (SRCROOT) /../ react-native / React 및 $ (SRCROOT) /../../ React를 모두 포함하는지 확인하십시오. 둘 다 재귀로 표시하십시오.
  3. 프로젝트 실행 (Cmd + R)

그런 다음 자바 스크립트 땅으로 돌아갑니다.

react-native-keyboardevents를 가져와야합니다.

var KeyboardEvents = require('react-native-keyboardevents');
var KeyboardEventEmitter = KeyboardEvents.Emitter;

그런 다음보기에서 키보드 공간에 대한 상태를 추가하고 키보드 이벤트 수신에서 업데이트합니다.

  getInitialState: function() {
    KeyboardEventEmitter.on(KeyboardEvents.KeyboardDidShowEvent, (frames) => {
      this.setState({keyboardSpace: frames.end.height});
    });
    KeyboardEventEmitter.on(KeyboardEvents.KeyboardWillHideEvent, (frames) => {
      this.setState({keyboardSpace: 0});
    });

    return {
      keyboardSpace: 0,
    };
  },

마지막으로 모든 항목 아래의 렌더링 함수에 스페이서를 추가하여 크기가 커지면 물건을 부풀립니다.

<View style={{height: this.state.keyboardSpace}}></View>

애니메이션 API를 사용하는 것도 가능하지만 간단하게하기 위해 애니메이션 후에 조정합니다.


답변

react-native-keyboard-aware-scroll-view가 문제를 해결했습니다.
GitHub의 react-native-keyboard-aware-scroll-view


답변

이 시도:

import React, {
  DeviceEventEmitter,
  Dimensions
} from 'react-native';

getInitialState: function() {
  return {
    visibleHeight: Dimensions.get('window').height
  }
},

componentDidMount: function() {
  let self = this;

  DeviceEventEmitter.addListener('keyboardWillShow', function(e: Event) {
    self.keyboardWillShow(e);
  });

  DeviceEventEmitter.addListener('keyboardWillHide', function(e: Event) {
      self.keyboardWillHide(e);
  });
}

keyboardWillShow (e) {
  let newSize = Dimensions.get('window').height - e.endCoordinates.height;
  this.setState({visibleHeight: newSize});
},

keyboardWillHide (e) {
  this.setState({visibleHeight: Dimensions.get('window').height});
},

render: function() {
  return (<View style={{height: this.state.visibleHeight}}>your view code here...</View>);
}

그것은 나를 위해 일했습니다. 보기는 기본적으로 키보드가 표시 될 때 축소되고 숨겨지면 다시 자랍니다.


답변

언급하고 싶은데, 이제 KeyboardAvoidingViewRN에 있습니다. 가져 와서 RN의 다른 모듈로 사용하기 만하면됩니다.

다음은 RN의 커밋 링크입니다.

https://github.com/facebook/react-native/commit/8b78846a9501ef9c5ce9d1e18ee104bfae76af2e

0.29.0부터 사용 가능

UIExplorer에 대한 예제도 포함되어 있습니다.