i6mi6 / react-native-parallax-scroll-view

A ScrollView-like component with parallax and sticky header support.
ISC License
2.28k stars 379 forks source link

Add StickyHeaderOffset #162

Open bpeck81 opened 7 months ago

bpeck81 commented 7 months ago

I needed my sticky header to appear after a certain point and have the fixed header overlay it. I'm sharing this in case anyone else wants to do the same

Today I used patch-package to patch react-native-parallax-scroll-view@0.21.3 for the project I'm working on.

Here is the diff that solved my problem:

diff --git a/node_modules/react-native-parallax-scroll-view/src/index.js b/node_modules/react-native-parallax-scroll-view/src/index.js
index 8787b6f..0df833b 100644
--- a/node_modules/react-native-parallax-scroll-view/src/index.js
+++ b/node_modules/react-native-parallax-scroll-view/src/index.js
@@ -40,6 +40,7 @@ const IPropTypes = {
    renderScrollComponent: func,
    renderStickyHeader: func,
    stickyHeaderHeight: number,
+   stickyHeaderOffset: number,
    contentContainerStyle: ViewPropTypes.style,
    outputScaleValue: number
 }
@@ -87,6 +88,7 @@ class ParallaxScrollView extends Component {
            renderForeground,
            renderParallaxHeader,
            renderScrollComponent,
+           stickyHeaderOffset,
            renderStickyHeader,
            stickyHeaderHeight,
            style,
@@ -122,6 +124,7 @@ class ParallaxScrollView extends Component {
            stickyHeaderHeight,
            backgroundColor,
            renderFixedHeader,
+           stickyHeaderOffset,
            renderStickyHeader
        })
        const scrollElement = renderScrollComponent(scrollViewProps)
@@ -157,7 +160,7 @@ class ParallaxScrollView extends Component {
    * Expose `ScrollView` API so this component is composable with any component that expects a `ScrollView`.
    */
    getScrollResponder() {
-       return this.refs[SCROLLVIEW_REF]._component.getScrollResponder()
+       return this.refs[SCROLLVIEW_REF].getScrollResponder()
    }
    getScrollableNode() {
        return this.getScrollResponder().getScrollableNode()
@@ -367,6 +370,7 @@ class ParallaxScrollView extends Component {
        stickyHeaderHeight,
        backgroundColor,
        renderFixedHeader,
+       stickyHeaderOffset,
        renderStickyHeader
    }) {
        const { viewWidth } = this.state
@@ -374,45 +378,35 @@ class ParallaxScrollView extends Component {
        if (renderStickyHeader || renderFixedHeader) {
            const p = pivotPoint(parallaxHeaderHeight, stickyHeaderHeight)
            return (
-               <View
-                   style={[
-                       styles.stickyHeader,
-                       {
-                           width: viewWidth,
-                           ...(stickyHeaderHeight ? { height: stickyHeaderHeight } : null)
-                       }
-                   ]}
-               >
-                   {renderStickyHeader
-                       ? <Animated.View
-                           style={{
-                               backgroundColor: backgroundColor,
-                               height: stickyHeaderHeight,
-                               opacity: interpolate(scrollY, {
-                                   inputRange: [0, p],
-                                   outputRange: [0, 1],
-                                   extrapolate: 'clamp'
-                               })
-                           }}
-                       >
-                           <Animated.View
+               <View style={{ top: 0, position: 'absolute', width: '100%' }}>
+                   {renderFixedHeader && renderFixedHeader()}
+
+                   <View
+                       style={[
+                           styles.stickyHeader,
+                           {
+                               width: viewWidth,
+                               ...(stickyHeaderHeight ? { height: stickyHeaderHeight } : null)
+                           }
+                       ]}
+                   >
+                       {renderStickyHeader
+                           ? <Animated.View
                                style={{
-                                   transform: [
-                                       {
-                                           translateY: interpolate(scrollY, {
-                                               inputRange: [0, p],
-                                               outputRange: [stickyHeaderHeight, 0],
-                                               extrapolate: 'clamp'
-                                           })
-                                       }
-                                   ]
+                                   backgroundColor: 'transparent',
+                                   height: stickyHeaderHeight,
+                                   opacity: interpolate(scrollY, {
+                                       inputRange: [stickyHeaderOffset ? stickyHeaderOffset : 0, p + (stickyHeaderOffset != null ? stickyHeaderOffset : 0)],
+                                       // inputRange: [0, p],
+                                       outputRange: [0, 1],
+                                       extrapolate: 'clamp'
+                                   })
                                }}
                            >
                                {renderStickyHeader()}
                            </Animated.View>
-                       </Animated.View>
-                       : null}
-                   {renderFixedHeader && renderFixedHeader()}
+                           : null}
+                   </View>
                </View>
            )
        } else {
@@ -435,6 +429,7 @@ ParallaxScrollView.defaultProps = {
    renderParallaxHeader: renderEmpty, // Deprecated (will be removed in 0.18.0)
    renderForeground: null,
    stickyHeaderHeight: 0,
+   stickyHeaderOffset: null,
    contentContainerStyle: null,
    outputScaleValue: 5
 }

This issue body was partially generated by patch-package.

apfritts commented 3 months ago

This may be resolved by #129. Feedback is welcome if someone can confirm.