The accepted solution did not work well for me because I need to put flexGrow: 1
on the contentContainerStyle. Using insets/offsets didn't make the content grow the way I want, otherwise it worked not so bad.
I have another solution to suggest: putting a bicolor background layer under a transparent ScrollView, and add colors to your scrollview content. This way, on ios bounce, the bicolor layer under the scrollview will reveal itself.
Here's what I mean by bicolor layer (here the scrollview is empty and transparent)

Now if I put back the ScrollView children (which if a body with blank background, and a footer with yellow background), I get this:

As long as you don't bounce more than 50% of the scrollview height, you will see the appropriate background color.
Here's a component you can use to wrap your scrollview.
const AppScrollViewIOSBounceColorsWrapper = ({
topBounceColor,
bottomBounceColor,
children,
...props
}) => {
return (
<View {...props} style={[{ position: 'relative' }, props.style]}>
{children}
<View
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
zIndex: -1, // appear under the scrollview
}}
>
<View
style={{ flex: 1, backgroundColor: topBounceColor }}
/>
<View
style={{ flex: 1, backgroundColor: bottomBounceColor }}
/>
</View>
</View>
);
};
And here's how you use it:
<AppScrollViewIOSBounceColorsWrapper
style={{flex: 1}}
topBounceColor="white"
bottomBounceColor="yellowLancey"
>
<ScrollView style={{flex: 1}}>
<WhiteBackgroundBody/>
<YellowBackgroundFooter />
</AppScrollView>
</AppScrollViewIOSBounceColorsWrapper>
Make sure to NOT set a background color to the scrollview, otherwise the bicolor layer will never reveal itself (backgroundColor on contentContainerStyle is fine)