You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中如何让上层View触发onPress同时将触摸事件透传给下层视图

你之前设置pointerEvents="none"之后,上层视图会完全不接收所有触摸事件,所以onPress自然不会触发,不能用这个属性来实现同时响应的需求,可通过以下两种方案实现:

方案1:基于RN原生手势响应系统实现(无额外依赖)

不需要引入第三方库,通过RN自带的手势响应回调控制事件同时透传给下层ScrollView,自己实现点击逻辑判定即可:

import { useState } from 'react';
import { View, ScrollView, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  containingTouchable: {
    position: 'absolute',
    top: 0,
    right: 0,
    left: 0,
    bottom: 0,
    backgroundColor: 'rgba(100,100,100,0.3)',
    zIndex: 999, // 确保上层视图在最前
  },
});

const Component = () => {
  // 记录触摸起始信息,用于判断是否为点击
  const [touchStartInfo, setTouchStartInfo] = useState(null);

  const handleTouchStart = (e) => {
    const { pageX, pageY, timestamp } = e.nativeEvent;
    setTouchStartInfo({ x: pageX, y: pageY, time: timestamp });
  };

  const handleTouchEnd = (e) => {
    if (!touchStartInfo) return;
    const { pageX, pageY, timestamp } = e.nativeEvent;
    // 判定规则:触摸时长小于200ms,偏移量小于10px则视为点击,可根据业务调整阈值
    const duration = timestamp - touchStartInfo.time;
    const offsetX = Math.abs(pageX - touchStartInfo.x);
    const offsetY = Math.abs(pageY - touchStartInfo.y);
    if (duration < 200 && offsetX < 10 && offsetY < 10) {
      console.warn('pressed me');
    }
    setTouchStartInfo(null);
  };

  // 允许当前视图响应触摸
  const onShouldSetResponder = () => true;
  // 允许下层视图同时响应触摸,不会拦截ScrollView的滚动事件
  const onResponderTerminationRequest = () => false;

  return (
    <>
      <View
        style={styles.containingTouchable}
        onTouchStart={handleTouchStart}
        onTouchEnd={handleTouchEnd}
        onShouldSetResponder={onShouldSetResponder}
        onResponderTerminationRequest={onResponderTerminationRequest}
      />
      <ScrollView>
        {/* ScrollView原有内容 */}
      </ScrollView>
    </>
  );
};

方案2:使用react-native-gesture-handler实现(代码更简洁)

如果你项目中已经接入了react-native-gesture-handler,可以直接通过配置手势并发响应实现:

import { ScrollView, StyleSheet, View } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';

const styles = StyleSheet.create({
  containingTouchable: {
    position: 'absolute',
    top: 0,
    right: 0,
    left: 0,
    bottom: 0,
    backgroundColor: 'rgba(100,100,100,0.3)',
  },
});

const Component = () => {
  const tapGesture = Gesture.Tap()
    .onEnd(() => {
      console.warn('pressed me');
    })
    // 允许点击手势和ScrollView的滚动手势同时响应
    .simultaneousWithExternalGesture(ScrollView);

  return (
    <>
      <GestureDetector gesture={tapGesture}>
        <View style={styles.containingTouchable} />
      </GestureDetector>
      <ScrollView>
        {/* ScrollView原有内容 */}
      </ScrollView>
    </>
  );
};

内容的提问来源于stack exchange,提问作者Banky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:45:09