onTouchGesture:原生触摸事件
onTouchGesture 在 iOS 18+ 通过 UIKit 获取每根手指的触摸阶段。适合自定义键盘的按键或整行专用触摸区,SwiftUI 继续负责布局,脚本判断点按、长按和划动。它是可选的新路径,不会自动改变 DragGesture。iOS 17 忽略此属性,不安装替代手势;旧系统兼容路径须由脚本明确选择。
属性
回调同步运行,应保持简短。不要等待 Promise 或逐事件同步写盘。主线程/JS 阻塞仍会影响响应,本接口不保证延迟上限。
事件字段
receivedAt - timestamp 观察事件投递等待,dispatchAt - receivedAt 观察原生处理到 JS 调用前的等待,均不是画面呈现延迟。合成取消事件的 timestamp 为取消时刻。不能直接与 Date.now() 或未校准的 performance.now() 相减。
不提供 predictedEndLocation / predictedEndTranslation,速度也不保证与 SwiftUI 估计相同。依赖速度/预测来取消长按的脚本需要适配和验证启发式,不应伪造预测字段。
归属、取消与兼容
逐指保存 touchId 状态。单指状态机可以采用“第一根持有,其他手指整段忽略”,不能让第二根手指提交/结束第一根。整行通过初始位置命中扩大的按键区域,移动后仍保留初始目标。
初始触点按绑定视图的 local 布局矩形过滤,不提供任意 contentShape 或额外 hitSlop 的等价语义。需要扩大的命中区域时,先扩大专用触摸视图的实际 frame。
禁用、视图移除、系统取消和键盘隐藏/切换会取消活跃触摸。取消时停止长按、删除和光标 repeat,清理 popup/highlight,不要调用提交点按的 end/settle。脚本退出后不应依赖还能收到 JS 回调;组件 cleanup 也须清理计时器和状态。
该接口不是 GestureInfo,不接受 GestureMask,不能传入 gesture、highPriorityGesture 或 simultaneousGesture。它保留布局,但不保证与子级按钮、滚动和菜单的手势竞争关系等价。仅绑定专用输入区;整行与单键不要重叠,同一区域不要同时安装旧拖动路径。候选滚动、contextMenu、工具栏及系统键盘切换保留原交互。
完整多指输入还需要脚本隔离长按、repeat、光标等共享状态;增加此接口不等于单指键盘自动支持多指。保留显式回退开关,切换前取消活跃手势。
