Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pull Scrollview to reveal View - React Native

I'm trying to build something similar to IMessage's and WhatsApp's header in react native, where users can pull down to reveal a search bar in the header.

pullToRevealView

I have been able to pull down to reveal a hidden input, but because the scrollview's y value becomes negative on pull, it will bounce back to y = 0 and prevent the input from sticking to the top. I have tried using both translateY and scaleY to reveal the hidden input.

class List extends Component {

  scrollY = new Animated.Value(0)

  render() {
    const translateY = this.props.scrollY.interpolate({
      inputRange: [ -50, 0 ],
      outputRange: [ 50, 0 ],
      extrapolate: 'clamp',
    })

   return (
    <>
       <Animated.View style={[
        styles.container,
        { transform: [ { translateY } ] },
       ]}>
          <Input />
       </Animated.View>

       <Animated.ScrollView
         onScroll={Animated.event(
           [ { nativeEvent: { contentOffset: { y: this.scrollY } } } ],
           { useNativeDriver: true }
          )}
         scrollEventThrottle={16}
       >
        {...}
       </Animated.ScrollView>
     </>
   )
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: colors.white,
    width: windowWidth,
    height: 50,
    position: 'absolute',
    top: -50,
    zIndex: -99,
  },
});

I found this Stack Overflow post that has been useful to reference but it is IOS specific Pull down to show view

like image 947
Gnardog Avatar asked Aug 29 '19 18:08

Gnardog


2 Answers

I solved this by using contentOffset and without any animations. I needed to make sure the scrollview was at least the size of the phone's windowHeight and then used contentOffset to push the initial y value of the Scrollview to the size of the header

      <ScrollView
        ListHeaderComponent={() => (
          <Header headerHeight={hiddenHeaderHeight} />
        )}
        contentContainerStyle={{ minHeight: windowHeight }}
        contentOffset={{ y: hiddenHeaderHeight }}
        ...

This solution works for a Flatlist as well.

One thing to note is contentOffset is an ios specific prop

like image 196
Gnardog Avatar answered Nov 13 '22 09:11

Gnardog


check out this medium article. It provides a detailed explanation of how to do something similar to your desired behavior.

like image 23
thorondor Avatar answered Nov 13 '22 07:11

thorondor