We are trying to repeat the same thing that was done is this plugin: https://github.com/mapsplugin/cordova-plugin-googlemaps/blob/master/README.md (How does this plugin work) but using react-native + mapbox gl(native).
The idea is simple: webview and mapview are "siblings", webview is above mapview and part of webview is transparent and mapview is shown under it. We would like any touch events that occur in this transparent area not to be captured by webview and bubble/whatever to mapview so you can touch/drag/zoom map.
Simply said: we want part(not all of it) of webview not to capture events, but to allow underlying view to capture them.
It looks like there are some methods in react native that allow to do that(conditionally control event capture) (https://facebook.github.io/react-native/docs/view.html#onstartshouldsetrespondercapture ) but we can't find any working example to test it and we can't completely understand documentation that is provided (we can't even understand should this callback be specified for parent view or child views).
So basically we just need some instrument in react-native to conditionally capture touch events.
Can anyone help us with it? Example with map/webview may be too complicated, any conditional capture of events in two views should help a lot.
Each touch event is automatically logged as a breadcrumb and displays on the dashboard when an event occurs along with the component tree in which the touch event occurred. This component tree is logged using the name property of a component. By default, React Native will set this property automatically on components.
js */ import React from "react"; import { Button, StyleSheet, Text, View } from "react-native"; function App() { const getDeviceType = (e) => { console. log(e); }; return ( <View style={styles. app} pointerEvents="box-none"> <View style={styles. header}> <Text style={styles.
React Native uses a JavaScript runtime, but the UI is not HTML and it doesn't use a WebView. You use JSX and React Native specific components to define the UI. It provides a native-level performance and look and feel but some UI parts have to be configured separately for iOS and Android.
Import the React Native WebView package in App. js . We will create a normal HTML page in WebView and use “script” tags to let the HTML page communicate with the React Native app. In the “script” tag, we are going to call a sendDataToReactNativeApp() function in which we will use a window property called window.
I am not sure if this is the perfect solution but what you can do is to create an EvenEmitter and just make the Webview catch all of the clicks. The ones that should be handled by the Map, can me sent to the map itself.
I use them on screens, where multiple components might be created but they can be emitted to the parent screen. It is mostly used to handle modal screens.
import EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter';
this._eventEmitter = new EventEmitter();
this._eventEmitter.addListener('modal', (data) => {
this.setState({
visibleModal: true,
modalData: data
});
});
Then you can use them like emitter.emit("modal", data)
Edit:
Here is another approach, which also shows you how you can use the methods you were asking in the question.
class Class extends Component {
onStartShouldSetResponder = () => true;
onEvent = (e) => {
let object = {};
object.locationX = e.nativeEvent.locationX;
object.locationY = e.nativeEvent.locationY;
object.pageY = e.nativeEvent.pageY;
object.pageX = e.nativeEvent.pageX;
object.target = e.nativeEvent.target;
//object.touches = e.nativeEvent.touches; //These will trigger a cyclic error while parsing but you can access them
//object.changedTouches = e.nativeEvent.changedTouches;
object.identifier = e.nativeEvent.identifier;
alert(JSON.stringify(object));
if (object.pageX > this.state.x && object.pageX < (this.state.x + this.state.width) && object.pageY > this.state.y && object.pageY < (this.state.y + this.state.height))
alert("inside") //Here you can trigger whatever function you need from the underlying view
}
onLayout = (event) => {
this.setState({
x: event.nativeEvent.layout.x,
y: event.nativeEvent.layout.y,
width: event.nativeEvent.layout.width,
height: event.nativeEvent.layout.height,
});
}
render(){
return(
<ScrollView>
<View ref={"target"} style={{
position: 'absolute',
height: 200,
width: 200,
left: 100,
top: 100,
backgroundColor: 'rgba(0,0,0,0.5)'
}}
onLayout={this.onLayout}
/>
<View
onl
onStartShouldSetResponder={this.onStartShouldSetResponder}
onResponderMove={this.onEvent}
style={{
backgroundColor: 'rgba(255,0,0,0.3)',
width: '100%',
height: 150
}}/>
<TouchableWithoutFeedback
onPress={this.onEvent}
onLongPress={this.onEvent}
style={{
backgroundColor: 'rgba(0,255,0,0.3)',
width: '100%',
height: 150
}}>
<View style={{height: 150, backgroundColor: 'rgba(0,255,0,0.3)'}}/>
</TouchableWithoutFeedback>
<View
onTouchStart={this.onEvent}
onTouchEnd={this.onEvent}
style={{
backgroundColor: 'rgba(0,0,255,0.3)',
width: '100%',
height: 150
}}>
</View>
</ScrollView>
);
}
}
Maybe this will help you pass events to the other views
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With