Clickable Background underneath a ScrollView [React Native]

Viewed 2378

So, I want to create a layout similar to whats below. [Refer the Image]

So the background has a full screen MapView (React Native Maps) with Markers over it, which needs to be clickable.

And there is a Scrollview with full screen height over the MapView which initially has some top-margin associated with its contents.

But the issue if I arrange my Views this way, the Markers on the map are not clickable in the initial state.

<View>
  <MapView>
    <Marker clickEventHere></Marker>
    <Marker clickEventHere></Marker>
  </MapView>
  <ScrollView fullscreen>
     <View marginTop></View>
  </ScrollView>
<View>

I am unsure if its really possible to solve this out.

Initial State Initial State

After Scrolling After Scrolling

Solution Tried

yScrolled = event.nativeEvent.contentOffset.y;
yValue = this.state.yValue - yScrolled;

upwardScroll = yScrolled > 0;

if(upwardScroll && (yValue > 0)){
  this.setState({
    yValue: yValue
  });
}


if(yScrolled === 0){
  yScrolled = -10;
}
if(!upwardScroll && (yValue <= scrollViewMarginTop)){
  yValue = this.state.yValue - yScrolled;
  console.debug("UPDATE DOWNWARD");
  this.setState({
    yValue: yValue
  });
}
2 Answers

I'd start with adding absolute positioning to your ScrollView, (position: absolute) starting at whatever y coordinate you would like. I would make this y value a state, eg

yValue: new Animated.Value(start_value) or simply yValue: start_value

I would then use ScrollView's prop onScroll event to handle the change in this y coordinate, for example for the first 100 pixels of a scroll it would simply change the yValue instead of scrolling the view.

This should enable you to press the markers you have in your parent view, and use the same component structure that you have provided.

Note: You would need to do this for collapsing the scrollview also.

Note2: if this doesn't give you the result you were looking for, i'd suggest looking into using some sort of collapsable component for this task, eg https://github.com/oblador/react-native-collapsible

Hope this helps

EDIT: To collapse the scrollview you could first identify if the scroll direction is downwards ( which i think youve done via upwardScroll ) and then..

1) Either simply add the content offset to your yValue

2) If you used Animated.Value for yValue, you can have an animate function that animates the scrollview downwards to your desired position. I think this would look nicer as the user would only need a simple downwards flick to collapse the view, which seems like the industry standard.

There is also a library that is called react-native-touch-through-view that can do this for you. This it how it works basically:

<View style={{ flex: 1 }}>
    // Your map goes here
</View>
<TouchThroughWrapper style={{
    position: 'absolute'',
    top:      0,
    left:     0,
    width:    '100%',
    height:   '100%',
}}>
    <ScrollView
        style={{
            backgroundColor: 'transparent',
            position:        'absolute',
            top:             0,
            left:            0,
            width:           '100%',
            height:          '100%',
            // Maybe in your case is flex: 1 enough
        }}
        bounces={false}
        showsVerticalScrollIndicator={false}
    >
        <TouchThroughView 
            style={{
                height: 400, // This is the "initial space" to the top
            }} 
        />
        // The "slide up stuff" goes here
    </ScrollView>
</TouchThroughWrapper>

For example, this then can look like this:

ios screenshot

So the map is overlayed by the TouchThroughView that passes all the events right to the view behind. In my case this worked better than using pointer-events box-none.

Related