bamlab / react-native-image-header-scroll-view

ScrollView with an image in header which becomes a navbar
MIT License
997 stars 99 forks source link

TriggeringView doesn't update threshold if renderHeader() component updates its height #23

Open fsarachu opened 7 years ago

fsarachu commented 7 years ago

Hey, first of all, thank you for this amazing work!

I'm using it in a special scenario where the header component height is calculated dynamically (using react-native-auto-height-image).

This would be my code:

import React, {Component} from "react";
import {Text, View} from "react-native";

import AutoHeightImage from 'react-native-auto-height-image';
import HeaderImageScrollView, {TriggeringView} from 'react-native-image-header-scroll-view';

const DEFAULT_HEADER_HEIGHT = 500;

export default class WallScreen extends Component {

    componentWillMount() {
        this._setHeaderHeight(DEFAULT_HEADER_HEIGHT);
    }

    render() {

        return (
            <View style={styles.container}>

                <HeaderImageScrollView
                    maxHeight={this.props.headerHeight} // Prop coming from redux state.
                    minHeight={0}
                    fadeOutForeground={true}
                    renderHeader={this._renderHeader.bind(this)}
                >

                    <TriggeringView
                        onHide={this._onHide.bind(this)}
                        onDisplay={this._onDisplay.bind(this)}
                    >
                    </TriggeringView>

                    <Text>
                        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam asperiores at commodi cumque
                        dolor dolorum, ea eaque est excepturi nam, perferendis perspiciatis, porro! A illo ipsa itaque
                        quae rerum unde?
                    </Text>

                </HeaderImageScrollView>

            </View>
        );

    }

    _setHeaderHeight(height){
        // Here I would dispatch the redux action to update 'headerHeight'.
    }

    _renderHeader() {
        return (
            <View>
                <AutoHeightImage
                    width={360} // Hardcoded, not important for this example
                    imageURL='https://example.com'
                    onHeightChange={this._setHeaderHeight.bind(this)}
                />
            </View>
        );
    }

    _onHide() {
        console.log('On hide called');
    }

    _onDisplay() {
        console.log('On display called')
    }

}

Until now, all great! All the layout works great out of the box and my code updates the header height correctly!

BUT the problem comes with TriggeringView. As you can see, the header height is initialized at 500. Well, as I update the headerHeight prop via redux, TriggeringView will still trigger the onHide and onDisplay callbacks using the 500 initial height.

I took a look at the source and saw that the triggering threshold is based in the initialPageY property, and this property is calculated in the onLayout hook. So the problem is this that hook is not triggered when the header height changes.

PS: I fixed this adding a new dynamicHeaderHeight prop to HeaderScrollView. Will submit a PR today!

Thanks!