Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React native ScrollView disable one direction on condition

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

like image 427
Aharon Vishinsky Avatar asked Mar 29 '18 06:03

Aharon Vishinsky


2 Answers

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

like image 85
Tim Avatar answered Oct 23 '22 09:10

Tim


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.

like image 43
hakkikonu Avatar answered Oct 23 '22 07:10

hakkikonu