codeherence / react-native-header

A high-performance, cross-platform animated header component for React Native applications.
MIT License
218 stars 15 forks source link

Fade in Header component *before* fully scrolled through Large Header #14

Closed bencreynolds closed 1 year ago

bencreynolds commented 1 year ago

Taking a look at your Twitter example, it suffers the same issue I’m facing. I have a relatively large “LargeHeader” component. Scrolling through the header causes the main title to go off screen long before I reach the bottom of the component (which triggers the transition to show the “Header” component.

Hopefully that made sense. I can explain further if needed.

Maybe I’m missing something, but is there a way to trigger the “transition” much earlier in the scroll position?

Thanks.

e-younan commented 1 year ago

There isn't a way at the moment, however I was already thinking about adding something like this. If I understand you correctly, you want the transition between the LargeHeader and Header component to begin at some arbitrary y value, rather than the end of the LargeHeader, correct?

bencreynolds commented 1 year ago

There isn't a way at the moment, however I was already thinking about adding something like this. If I understand you correctly, you want the transition between the LargeHeader and Header component to begin at some arbitrary y value, rather than the end of the LargeHeader, correct?

Yes, or a percentage of the total LargeHeader height. So once you hit 50% of the LargeHeader scrolled off screen Header begins fading in.

e-younan commented 1 year ago

I'll think about how I will do this - the implementation currently fades the LargeHeader in and out based on whether or not it is shown. This was to mimic the iOS native large header animation that I looked at before (i.e., when the user scrolls to the top of a ScrollView, the large header will fade in quickly). The issue is that if I allow for a specific y to be the boundary between the transition, the rest of the LargeHeader will fade out even though it is still on the screen - I may have to disable the LargeHeader fading for this.

bencreynolds commented 1 year ago

Thanks! I'm interested in seeing how it turns out.

Also, while I have you, is there a way to not have the blank space on top of the LargeHeader component? From what I can tell, it just adds blank space to the top of the LargeHeader component equal to the height of the Header component.

e-younan commented 1 year ago

It doesn't actually. It ends up being a child component of the ScrollView, or swapped in as the HeaderComponent of the virtualized lists. Check out the source code, it's pretty straightforward.

If you have a screenshot or video, it'll help me figure out what space you're specifically referring to.

bencreynolds commented 1 year ago

It doesn't actually. It ends up being a child component of the ScrollView, or swapped in as the HeaderComponent of the virtualized lists. Check out the source code, it's pretty straightforward.

If you have a screenshot or video, it'll help me figure out what space you're specifically referring to.

Apologies for the delay, I swore I replied but I guess I didn't.

Here I am just adjusting the height of the "Header" component to be taller. Notice how it pushes the entire scrollview down despite not being rendered. That's not how it works on iOS natively. The Header would appear on top of the scrollview as the original header began moving off screen.

https://github.com/codeherence/react-native-header/assets/68837716/f2ff10ef-cd10-4061-b71e-a3eb665d21ae

e-younan commented 1 year ago

It doesn't actually. It ends up being a child component of the ScrollView, or swapped in as the HeaderComponent of the virtualized lists. Check out the source code, it's pretty straightforward.

If you have a screenshot or video, it'll help me figure out what space you're specifically referring to.

Apologies for the delay, I swore I replied but I guess I didn't.

Here I am just adjusting the height of the "Header" component to be taller. Notice how it pushes the entire scrollview down despite not being rendered. That's not how it works on iOS natively. The Header would appear on top of the scrollview as the original header began moving off screen.

https://github.com/codeherence/react-native-header/assets/68837716/f2ff10ef-cd10-4061-b71e-a3eb665d21ae

Are you using "MinorHeader" as the HeaderComponent in the scroll container, or the LargeHeaderComponent?

bencreynolds commented 1 year ago

@e-younan

I have a custom component for rendering the whole screen’s layout.

Here’s the current code for it:


const ScrollLayout = ({
    children,
    MajorHeader,
    MinorHeader,
}) => {

    const theme = useTheme();

    const LargeHeaderComponent = ({ scrollY }) => {
        return (
            <LargeHeader
                headerStyle={{ paddingVertical: 0, paddingHorizontal: 0 }}
            >
                <ScalingView scrollY={scrollY} endScale={1} style={{ flex: 1 }}>
                    <MajorHeader />
                </ScalingView>

            </LargeHeader>
        )
    }

    const HeaderComponent = ({ ignoreTopSafeArea, showNavBar, children }) => {
        return (
            <Header
                ignoreTopSafeArea={true}
                showNavBar={showNavBar}
                headerRightFadesIn
                headerLeftFadesIn
                borderColor={theme.primary}
                ignoreLeftSafeArea
                ignoreRightSafeArea
                headerCenter={
                    <Layout f={1}>
                        <MinorHeader />
                    </Layout>
                }
            />
        )
    }

    return (
        <Layout level={1} f={1}>
            <ScrollViewWithHeaders
                HeaderComponent={HeaderComponent}
                LargeHeaderComponent={LargeHeaderComponent}
            >
                {children}
            </ScrollViewWithHeaders>
        </Layout>
    )
}

The component is just a with some extra params in my app.

e-younan commented 1 year ago

This is intended by the implementation. At the moment, the HeaderComponent will sit above the scroll container, and the LargeHeaderComponent will end up as a child of it.

When I originally designed this, I made it so that the Header will stay fixed at the top, and have a general height that is similar to native primitives, and the LargeHeader would be a component that has a dynamic height.

So in your case, it's somewhat intended that the Header stay smaller, and you add the extra space as part of the LargeHeader instead.

e-younan commented 1 year ago

I'm working on this right now and will have a PR up in a few minutes. Sorry for the delay, have been quite busy with an application I was building.

e-younan commented 1 year ago

https://github.com/codeherence/react-native-header/pull/17

e-younan commented 1 year ago

This is released in 0.10.0, let me know if it works.