15

is it possible to scroll only to one direction? I have a function that detects the direction the user is a scroll.

But I can't figure out how can I set a flag, that if the user doesn't answer the question it will not allow him to scroll right only left?

thank you

Aharon Vishinsky
  • 373
  • 2
  • 5
  • 15
  • directionalLockEnabled - Will this be useful for you? https://facebook.github.io/react-native/docs/scrollview#directionallockenabled - Only on iOS – Ashwin Mothilal May 19 '19 at 12:55

3 Answers3

3

I have created a small example, where only scrolling to the right is allowed. Of course this example can be adapted to allow left scrolling in specific conditions. In the code, I marked the position where to add such a condition.

Demo

enter image description here

Explanation

The example consists of two main parts.

  1. Detecting the scroll direction and disable scroll if necessary
  2. Enabling the scroll again

Detecting scroll direction

See code comments for explanation

handleScroll(event){
      // WIDTH originates from Dimensions.get('screen').width
      const endOfView = event.nativeEvent.contentSize.width - WIDTH; 
      const positionX = event.nativeEvent.contentOffset.x; 
      const positionY = event.nativeEvent.contentOffset.y; 

      // check if we are scrolling left, also detect if we are at the end of the scrollview 
      // MARKED: check other conditions here to allow scrolling again
      if(this.state.lastPositionX > positionX && endOfView > positionX){
        // we are scrolling left, disable scroll, reset the current position
        this.setState({ lastPositionX: positionX, lastPositionY: positionY, allowScroll: false });
        // scroll back to last valid position. Important! Otherwise users may be able to scroll left
        this._scrollview.scrollTo({x: this.state.lastPositionX, y: this.state.lastPositionY});
        //call the timer to enable scroll again 
        this.callTimer();
      }else{
        // we are scrolling right, everthing is fine
        this.setState({ lastPositionX: positionX, lastPositionY: positionY });
      }
    }

Enabling scroll again:

We are making use of a timer to enable scroll again after a specified amount of time.

timerFn() {
  // clear the timer again, otherwise the timer will fire over and over again 
  clearInterval(this.state.timer);
  //enable scroll and reset timer 
  this.setState({allowScroll: true, timer: null });

}
callTimer() {
  if (this.state.timer == null ){ 
    // no timer is available, we create a new one. Maybe you have to fine tune the duration 
    let timer = setInterval(() => this.timerFn(), 1000);
    this.setState({timer});
  }
}

Render:

  <SafeAreaView style={styles.container}>
   <ScrollView
   horizontal
   scrollEventThrottle={15}
   scrollEnabled={this.state.allowScroll}
   onScroll={(event) => this.handleScroll(event)}
   ref={view => this._scrollview = view}
   >
     <View style={{width: WIDTH, backgroundColor: 'red'}} />
     <View style={{width: WIDTH, backgroundColor: 'green'}} />
     <View style={{width: WIDTH, backgroundColor: 'blue'}} />
   </ScrollView>
  </SafeAreaView>

Working Example

https://snack.expo.io/rJAamRC2E

Tim
  • 10,459
  • 4
  • 36
  • 47
1

You can use react-native-directed-scrollview package

Package: https://www.npmjs.com/package/react-native-directed-scrollview

This package has scrollTo({x: 100, y: 100, animated: true}) method. if you restrict x-axis coordinate to your conditions, it will be ok.

So try something like this,

if(isAnswered == false){
  scrollTo({x: /*x-axis position*/, y: /*y-axis position*/, animated: true})
}

note: you can pass false to animated parameter. It is optional.

hakki
  • 6,181
  • 6
  • 62
  • 106
  • no need to use an additional package. The [scrollTo](https://facebook.github.io/react-native/docs/scrollview#scrollto) function is available for the standard `ScrollView` – Tim May 19 '19 at 13:28
0

For anyone who wants a fixed-height container with hidden content but need the RefreshControl functionality of a ScrollView, what i did was used a ScrollView but fixed its height.

When i want to show other content i animate the height/opacity of each content block to give the effect of scrolling.

<ScrollView
    refreshControl={...}
    style={{ height: contentBlockHeight, overflow: 'hidden' }}
    contentContainerStyle={{ height: contentBlockHeight, overflow: 'hidden' }}
>
...
</ScrollView>
Francis Leigh
  • 1,870
  • 10
  • 25