Force Touch 手势(iOS only)深度指南:react-native-gesture-handler 按压力识别从配置到源码 移动开发UI组件【免费下载链接】react-native-gesture-handlerDeclarative API exposing platform native touch and gesture system to React Native.项目地址https://gitcode.com/gh_mirrors/re/react-native-gesture-handler点击查看免费下载本指南围绕 react-native-gesture-handler 2.x 版本中的ForceTouchGesture按压力手势展开系统讲解它的行为模型、专属与通用配置、回调与事件数据结构并结合仓库源码TypeScript 手势对象与 iOS 原生UIGestureRecognizer实现剖析其激活/失败判定、压力计算与触觉反馈的真实工作方式。读完本文你将掌握如何用Gesture.ForceTouch()构建支持 3D Touch 压力感知的交互并学会在多平台下正确降级、避免把它当作关键功能依赖。一、概述识别触摸压力的连续手势ForceTouchGesture是一个连续手势用于识别触摸的压力大小允许在部分 iOS 设备上追踪触摸压力。它的核心行为如下当触摸压力大于或等于minForce时手势进入ACTIVE激活状态当压力大于maxForce时手势进入FAILED失败状态手势回调可用于持续跟踪触摸压力事件只提供第一根手指的压力信息手势开始时压力因子为0.0随压力增大按比例上升最大压力为1.0。弃用警告ForceTouchGesture已被标记为 deprecated将在 Gesture Handler 的未来版本中移除。在 ForceTouchGestureHandler.ts 与 forceTouchGesture.ts 的源码注释中均明确标注了这一点。由于该能力只在部分 iOS 设备上提供文档明确建议不应使用此手势定义任何关键行为只能作为额外增强同时确保所有功能在不使用该手势时也可访问。二、快速上手声明式 API 的最小示例2.x 新 API 使用Gesture.ForceTouch()创建手势对象并通过GestureDetector挂载到视图上import { GestureDetector, Gesture } from react-native-gesture-handler; function App() { // highlight-next-line const forceTouch Gesture.ForceTouch(); return ( GestureDetector gesture{forceTouch} View / /GestureDetector ); }从源码看Gesture.ForceTouch()在 gestureObjects.ts 中返回一个ForceTouchGesture实例其内部handlerName为ForceTouchGestureHandler见 forceTouchGesture.ts。GestureDetector会根据手势配置创建并更新对应的原生手势处理器支持手势组合识别详细说明可参考 gesture-detector.md。三、ForceTouchGesture专属配置以下属性是ForceTouchGesture特有的配置在源码中对应ForceTouchGestureConfig接口的三个可选字段见 ForceTouchGestureHandler.tsminForce(value: number)作用手势可以ACTIVE前所需的最小压力。取值范围[0.0, 1.0]。默认值0.2。源码佐证iOS 原生实现 RNForceTouchHandler.m 中定义了static const CGFloat defaultMinForce 0.2;并在resetConfig时恢复该默认值。maxForce(value: number)作用手势可承受的最大压力若压力超过此值手势进入FAILED状态。取值范围[0.0, 1.0]。默认值原生代码中为NAN即不设上限见 RNForceTouchHandler.m 的defaultMaxForce NAN。feedbackOnActivation(value: boolean)作用定义手势激活时是否执行触觉反馈haptic feedback。默认值false原生默认defaultFeedbackOnActivation NO。用法示例配置方法返回this以支持链式调用const forceTouch Gesture.ForceTouch() .minForce(0.3) .maxForce(0.9) .feedbackOnActivation(true) .onUpdate((event) { // 持续处理压力变化 console.log(event.force); });四、所有手势共享的通用配置除专属属性外ForceTouchGesture也继承所有手势通用的配置方法详见 base-gesture-config.mdenabled(value: boolean)指示该手势是否参与分析触摸事件流。设为false时可确保手势状态永远不会变为ACTIVE若手势已开始识别时更新该值状态会立即变为FAILED或CANCELLED取决于当前状态。默认值为true。shouldCancelWhenOutside(value: boolean)为true时手指离开所连接视图区域手势即取消或失败取决于当前状态。默认值依手势类型而异多数手势默认为falseLongPressGesture、TapGesture以及 Android/Web 上的NativeGesture默认为true。hitSlop(settings)控制所连接视图的哪些区域可用于开始识别手势传负数时视图四边按给定点数等量缩小可识别区域传对象时可分别指定left、right、top、bottom各边的缩减点数也可用horizontal/vertical代替或直接给width、height设置width时只能再指定right或left之一设置height时同理只能再指定top或bottom典型用法如left: 0, width: 20让手势只能在距左边缘 20 点内启动。重要该参数主要用于缩小可激活区域因此除width、height外各值只支持非正值0 或更低。Android 上允许正值以扩展到视图边界之外但不能超过父视图边界若要跨平台实现该效果应使用 React Native View 的hitSlop属性。withRef(ref)为手势对象设置 ref用于与旧 API 互操作。withTestId(testID)为手势对象设置testID便于在测试中查询该手势。cancelsTouchesInView(value)仅 iOS布尔值为true时手势进入ACTIVE状态会取消其连接的原生 UI 组件如UIButton、UISwitch上的触摸。默认值为true。runOnJS(value: boolean)安装react-native-reanimated后传给手势的回调默认会被 worklet 化并在 UI 线程执行。设为true时所有回调改在 JS 线程执行无论是否为 worklet。默认值为false。手势关系配置simultaneousWithExternalGesture(otherGesture1, otherGesture2, ...)添加应与本手势同时识别的手势。注意该方法只标记手势间的关系不会组合手势otherGestures仍需挂到另一个GestureDetector上才能被识别。requireExternalGestureToFail(otherGesture1, otherGesture2, ...)添加关系要求其他手势先失败本手势才能激活。blocksExternalGesture(otherGesture1, otherGesture2, ...)添加关系使其他手势一直等待激活直到本手势失败或完全不开始。activeCursor(value)仅 Web指定手势激活时使用的光标支持所有 CSS cursor 值如grab、zoom-in默认值为auto。五、连续手势共享配置作为连续手势ForceTouchGesture还支持manualActivation(value: boolean)为true时即使满足激活条件手势也不会自行激活你可以改用 state manager 手动操纵其状态。六、回调Callbacks所有手势共享的回调详见 base-gesture-callbacks.mdonBegin(callback)手势开始接收触摸时调用此时尚未激活也不知道是否会识别该手势。onStart(callback)手势被识别并转入激活状态时调用。onEnd(callback)已被识别的手势结束时调用仅当手势此前处于激活状态才会被调用。onFinalize(callback)手势完成处理时调用——无论是识别成功后结束还是识别失败。onTouchesDown(callback)每根手指放到屏幕上时调用。onTouchesMove(callback)手指在屏幕上移动时调用。onTouchesUp(callback)手指离开屏幕时调用。onTouchesCancelled(callback)手指停止被跟踪时调用例如手势结束。连续手势共享的回调详见 base-continuous-gesture-callbacks.mdonUpdate(callback)手势处于激活状态期间每次收到更新时调用。onChange(callback)手势激活期间每次收到更新时调用回调会收到相对于上一次事件的变化量信息。对于ForceTouchGestureonChange回调额外携带forceChange字段。源码 forceTouchGesture.ts 中通过changeEventCalculator计算第一次事件时forceChange current.force后续事件为current.force - previous.force。典型应用const forceTouch Gesture.ForceTouch() .onBegin(() { // 触摸开始但尚未确定是否识别 }) .onStart(() { // 压力达到 minForce手势激活 }) .onUpdate((event) { // 实时压力值 event.force }) .onEnd((event, success) { // 手指抬起或手势结束 }) .onFinalize((event, success) { // 结束或失败 });七、事件数据Event dataForceTouchGesture专属事件属性force触摸的压力值归一化到[0, 1]。事件负载的 TypeScript 类型定义见 GestureHandlerEventPayload.tsForceTouchGestureHandlerEventPayload除force外还包含x、y、absoluteX、absoluteY等坐标字段x/y为相对手势所连接视图的位置absoluteX/absoluteY为相对窗口的绝对位置推荐在手势引起视图变换时使用绝对坐标。所有手势共享的事件属性详见 base-gesture-event-data.mdstate手势当前状态以库导出的State对象下的常量表示。numberOfPointers当前屏幕上放置的指针手指数量。pointerType使用的指针设备类型由PointerType枚举表示包括TOUCH手指、STYLUS触控笔/数字笔、MOUSE鼠标、KEY键盘、OTHER其他未知设备类型。八、平台可用性与降级策略ForceTouchGesture的跨平台行为差异明显这一点在文档中明确强调也完全体现在源码里iOS提供完整原生实现见下节。Android没有任何实现ForceTouchGesture只是直接渲染 children不带任何 wrapper。WebforceTouchAvailable恒为false见 PlatformConstants.web.ts因此手势会回退到ForceTouchFallback。macOS原生代码中#if !TARGET_OS_OSX分支之外会输出RCTLogWarn(ForceTouchHandler is not supported on macOS)见 RNForceTouchHandler.m。运行时能力检测与回退渲染在 ForceTouchGestureHandler.ts 中手势处理器是否真正创建取决于PlatformConstants?.forceTouchAvailable为true时通过createHandler创建真实的ForceTouchGestureHandler为false时使用ForceTouchFallback—— 一个直接渲染 children 的组件并在挂载时通过console.warn提示开发者用ForceTouchGestureHandler.forceTouchAvailable进行条件渲染、提供适合自身场景的回退行为。forceTouchAvailable同时以静态属性的形式暴露(ForceTouchGestureHandler as ForceTouchGestureHandler).forceTouchAvailable其值来源于NativeModules.PlatformConstants/Platform.constants见 PlatformConstants.ts。因此推荐的降级写法是import { ForceTouchGestureHandler } from react-native-gesture-handler; function MyComponent() { if (ForceTouchGestureHandler.forceTouchAvailable) { return ForceTouchGestureHandler ... /; // 支持压力识别的实现 } return LongPressFallback /; // 不依赖压力的回退实现 }最佳实践由于仅在部分 iOS 设备上可用应把 Force Touch 视为增强手段——所有关键功能都必须在不依赖压力的交互下也能完成。九、源码级原理iOS 原生实现如何工作iOS 侧的原生实现位于 RNForceTouchHandler.m核心是一个自定义RNForceTouchGestureRecognizer继承UIGestureRecognizer。其工作逻辑可以从源码中精确还原1. 压力计算_force _firstTouch.force / _firstTouch.maximumPossibleForce;压力因子是当前触摸力与设备最大可能力之比因而被归一化到[0, 1]与文档中“最大压力为 1.0”的描述一致。手势开始时压力为 0随后按比例上升。2. 激活与失败判定- (BOOL)shouldActivate { return (_force _minForce); } - (BOOL)shouldFail { return TEST_MAX_IF_NOT_NAN(_force, _maxForce); }在touchesMoved中先处理压力再依次判定是否失败、是否激活_force _minForce满足时状态从Possible转为Began激活TEST_MAX_IF_NOT_NAN说明当maxForce为NAN默认值即未配置上限时不做失败判定只有配置了maxForce且压力超过它时手势才失败。3. 只跟踪第一根手指原生代码在touchesBegan中用_firstTouch [touches anyObject]记录第一根手指随后touchesMoved/touchesEnded都会先检查触摸集合是否包含_firstTouch不包含则直接忽略。这与文档中“提供第一根手指的压力信息”的描述完全一致。4. 触觉反馈if (_feedbackOnActivation) { [[[UIImpactFeedbackGenerator alloc] initWithStyle:(UIImpactFeedbackStyleMedium)] impactOccurred; }激活时若启用了feedbackOnActivation会触发UIImpactFeedbackStyleMedium冲击反馈在 TV 与 Vision 平台除外这正是“activation 时执行 haptic feedback”的底层实现。5. 事件负载eventExtraData:方法将压力、相对位置、绝对位置、触摸数量与指针类型打包进事件额外数据RNGestureHandlerEventExtraData forForce:...最终汇入 JS 侧事件负载的force等字段。十、注意事项与使用建议弃用状态ForceTouchGesture/ForceTouchGestureHandler在 2.x 中被明确标记为 deprecated源码 ForceTouchGestureHandler.ts 的 JSDoc 注释建议改用Gesture.ForceTouch()新 API而新 API 本身也标注了弃用并将在未来版本移除请勿在新项目中将其作为长期依赖。设备与平台限制仅部分 iOS 设备支持压力识别Android / Web 上没有任何实现Web 的forceTouchAvailable恒为falsemacOS 上不支持。降级兜底使用ForceTouchGestureHandler.forceTouchAvailable或PlatformConstants.forceTouchAvailable做能力检测为不支持压力识别的设备提供等价交互路径。定位为增强所有功能必须在不使用该手势时也可完整访问Force Touch 只能作为锦上添花的交互增强。组合使用可通过simultaneousWithExternalGesture、requireExternalGestureToFail、blocksExternalGesture等关系配置与其他手势协同手势的完整状态流转UNDETERMINED→BEGAN→ACTIVE→END或FAILED/CANCELLED可参阅 states-events.mdx。赞分享移动开发UI组件【免费下载链接】react-native-gesture-handlerDeclarative API exposing platform native touch and gesture system to React Native.项目地址https://gitcode.com/gh_mirrors/re/react-native-gesture-handler点击查看免费下载相关推荐uni-app force-press-gesture-handler 组件完全指南压力按压手势识别与手势协商uni app force press gesture handler 组件完全指南压力按压手势识别与手势协商 本文基于 uni app 开源仓库中的组件文档示例工程前端移动开发跨平台react-native-gesture-handler 长按手势指南LongPressGestureHandler 属性、事件数据与源码原理react native gesture handler 长按手势指南LongPressGestureHandler 属性、事件数据与源码原理 本指南聚焦 r移动开发UI组件如何为xi-editor写第一个插件30行Python搞定Echo插件教程如何为xi editor写第一个插件30行Python搞定Echo插件教程 xi editor 是一款后端用 Rust 编写的现代化文本编辑器它支持通过独立移动开发UI组件上一篇K9s AI事件调查终极指南快速根因分析和智能异常检测下一篇Linkding批量编辑工具5分钟搞定100个书签属性更新创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考