2016-06-23 3 views
2

시간표가 표시되는 앱이 있습니다.동시에 두 구성 요소를 동시에 스크롤

일정이 포함 된 오른쪽 ScrollView을 스크롤하면 스크롤 할 시간이 포함 된 왼쪽 ScrollView도 표시됩니다.

<ScrollView 
    ref={'leftScroll'} /> 

<ScrollView 
    ref={'rightScroll'} 
    scrollEventThrottle={1} 
    onScroll={(e) => this.refs.leftScroll.scrollTo({y: e.nativeEvent.contentOffset.y)} 
    onMomentumScroll={(e) => this.refs.leftScroll.scrollTo({y: e.nativeEvent.contentOffset.y)} /> 

우리는이 방법으로 스크롤 할 수 있지만 느리고 고르지 않습니다. 두 개의 스크롤을 완전히 동기화하는 방법이 있습니까? ScrollView?

이 디자인의 이유는 시간이 항상 화면의 왼쪽에 고정되어야하고, 객실은 항상 맨 위에 고정해야하며,이 경우에는 스케줄에서 스크롤.

답변

1

현재 React Native가 작동하는 방식으로 인해 매우 어렵습니다.

첫 번째 ScrollView은 주 스레드에서 스크롤 이벤트를 수신하고 그에 따라 스크롤됩니다. 그런 다음 React Native가 이벤트를 가져 와서 JS 스레드로 보내 JS 사이드에서 처리 할 수 ​​있고 onScroll 이벤트가 발생합니다. 그러면 처리기가 두 번째 ScrollView을 스크롤하는 메서드를 호출합니다. 즉, 새 스레드가 JS 스레드에서 주 스레드에서 실행되도록 예약되어 프로그래밍 방식의 스크롤이 발생할 수 있습니다.

따라서 이러한 모든 스케줄링과 메시지가 이러한 스레드간에 전달되므로 두 번째 ScrollView는 경험 한대로 항상 뒤떨어집니다.

정말 동기화하고 싶다면 기본 구현 (iOS에서는 1 구현, Android에서는 다른 구현)을 사용해야합니다. (iOS 용 상세)는 다음과 같이

한 가지 방법은 다음과 같습니다

  • 가의 2 reactTag (사용 React.findNodeHandle(component))를받을 방법이 것 custom native module 쓰기 ScrollView 당신은 동기화
  • 에 있고 싶어 당신이 UIScrollView *scrollView = [[[self bridge] uiManager] viewForReactTag:reactTag]
  • 같은 것을 사용하여 두 ScrollView에 대한 포인터를 얻을 수 있습니다 사용자 정의 모듈의 기본 측면에
  • 는 당신이 그에서 didScroll 이벤트에 후크가 흥미로운 부분이 온다 UIScrollView을 사용하면 맞춤 논리를 추가하여 동기화 상태를 유지할 수 있습니다. UIScrollView.delegate (원래 이벤트를 원래 대표자에게 전달하는 것을 잊지 않고)를 swizzle하거나 바꿀 수 있습니다. 가장 좋은 장소를 찾으려면 RCTScrollView을 광범위하게 살펴 보시기 바랍니다.

당신이 생각하기를 바란다;) 이것은 절대적으로 중요하지 않으며 iOS 프로그래밍에 대한 많은 경험이 있어야한다. 그러나 새로운 것을 배울 수있는 좋은 기회입니다.

+0

매우 간결한 설명 주셔서 감사합니다. 나는 아이폰 OS 개발자 였지만, 응용 프로그램을 "하이브리드"로 만드는 것은 피하고 싶었지만, 이것이 도약을 시도하는 것 같습니다. –

2

왼쪽에서 시간이있는 ScrollView와 오른쪽에 몇 가지 정보가있는 ScrollView가 비슷한 요구 사항을 가지고 있습니다.

onMomentumScroll을 사용하지 않아도 위의 코드를 약간 변경하면 부드러운 네이티브 반응을 얻을 수있었습니다.중요

onScroll={(e) => this.refs.timeScroll.scrollTo({y: e.nativeEvent.contentOffset.y, animated: false})} 

https://facebook.github.io/react-native/docs/scrollview.html#scrolltoscrollEventThrottle={16}이 그렇지 않으면 다시 스크롤 고르지 할 필요가 있음을 참고 : 워드 프로세서에서 그들은 scrollTo 방법에 애니메이션 속성을 언급. 반응 네이티브 1-16에 띄는없는 값 문서의 언급 - 그래서 사용을 16

편집 : 나는 내가 와서이에 대한 업데이트를 제공 거라고 생각

. 내 위의 솔루션을 어느 정도까지 일한, 그러나 그것은 여전히 ​​눈에 띄게 끝나는 작은 지연이 있습니다.

결국 결국 네이티브 만 사용하기 때문에 Animated를 구현하게되었습니다.

정의 :

const yOffset = new Animated.Value(0); 
const onScroll = Animated.event(
    [{ nativeEvent: { contentOffset: { y: yOffset } } }], 
    { useNativeDriver: true } 
); 

작성 방법 : Animated.View에

viewTranslate() { 
    return { 
     transform: [{ 
     translateY: yOffset.interpolate({ 
      inputRange: [0,1], 
      outputRange: [1,0] 
     }) 
     }] 
    }; 
    } 

할당 스타일 : Animated.ScrollView에

<Animated.View style={this.viewTranslate()>...</Animated.View> 

지정 이벤트 :

<Animated.ScrollView scrollEventThrottle={1} onScroll={onScroll}>...</Animated.ScrollView> 
관련 문제