Создать дыру в реагирующем веб-представлении для сенсорных событий
Мы пытаемся повторить то же самое, что было сделано с этим плагином: https://github.com/mapsplugin/cordova-plugin-googlemaps/blob/master/README.md (как работает этот плагин), но с использованием response-native + mapbox gl(родной).
Идея проста: веб-просмотр и просмотр карты - это "братья и сестры", веб-просмотр находится над просмотром карты, а часть веб-просмотра прозрачна, а отображение карты отображается под ним. Мы бы хотели, чтобы любые события касания, происходящие в этой прозрачной области, не регистрировались веб-обзором и всплывающими надписями / чем-либо другим, чтобы вы могли просматривать / перетаскивать / увеличивать карту.
Проще говоря: мы хотим, чтобы часть(а не вся) веб-просмотра не фиксировала события, а позволяла базовому представлению захватывать их.
Похоже, что есть некоторые методы в реагировать на нативные, которые позволяют сделать это (условно контролировать захват событий) ( https://facebook.github.io/react-native/docs/view.html), но мы не можем найти любой работающий пример, чтобы протестировать его, и мы не можем полностью понять предоставленную документацию (мы даже не можем понять, должен ли этот обратный вызов быть указан для родительского представления или дочерних представлений).
Так что в основном нам просто нужен какой-то инструмент в реагирующем режиме для условного захвата сенсорных событий.
Кто-нибудь может помочь нам с этим? Пример с картой / веб-просмотром может быть слишком сложным, любой условный захват событий в двух видах должен сильно помочь.
1 ответ
Я не уверен, что это идеальное решение, но что вы можете сделать, это создать EvenEmitter и просто заставить WebView перехватывать все клики. Те, которые должны обрабатываться картой, могут быть отправлены на саму карту.
Я использую их на экранах, где может быть создано несколько компонентов, но они могут быть отправлены на родительский экран. В основном он используется для обработки модальных экранов.
import EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter';
this._eventEmitter = new EventEmitter();
this._eventEmitter.addListener('modal', (data) => {
this.setState({
visibleModal: true,
modalData: data
});
});
Затем вы можете использовать их как emitter.emit("модальные", данные)
Редактировать:
Вот еще один подход, который также показывает, как вы можете использовать методы, которые вы задавали в вопросе.
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>
);
}
}
Может быть, это поможет вам передать события в другие представления