tunaSandwich
tunaSandwich

Reputation: 199

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

Upvotes: 11

Views: 3630

Answers (1)

tunaSandwich
tunaSandwich

Reputation: 199

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

Upvotes: 3

Related Questions