uni-app iOS侧滑返回拦截失败是因为系统级手势不触发onBackPress,需在pages.json中配置"popGesture":"close"关闭原生侧滑,再手动实现touch事件监听与动画退回。
原因是 onBackPress 默认不会处理手势返回;iOS 真机侧滑属于系统级导航行为,uni-app 的 JS 层完全接收不到事件。只有主动关闭原生侧滑,才能把控制权交回 WebView。
onBackPress 只会响应物理返回键或者 uni.navigateBack() 调用,无法感知 iOS 侧滑enablePullDownRefresh 一类底层开关,不过侧滑返回对应的开关名称是 popGesture,位置隐藏在 pages.json 中需要修改的是配置,而不是编写 JS。各页面应单独控制;全局配置只作用于新页面,已经打开的页面不会动态生效。
pages.json 相应页面的 style 节点下面添加:"popGesture": "none"
"popGesture": "close"(请注意:uni-app 文档中写的是 "none",实际测试发现 "close" 才能生效,而"none" 却可能被忽略)"none" 以后,物理返回键同样不会触发 onBackPress,因此需要手动监听 plus.key.addEventListener('backbutton')
{ "path": "pages/detail/detail", "style": { "popGesture": "close" }}
关闭原生侧滑仅是第一步;若要真正实现“自定义手势”,还需要自行接入 touchstart/touchmove/touchend,不过 WebView 的 touch 事件存在延迟、判断不准和容易误触的问题,在 iOS 上尤其明显。
<view> 绑定 @touchstart,应优先使用 uni.createSelectorQuery() 取得根容器后再监听,以免事件被滚动区域截断clientX 差值,还必须结合 touches[0].target 是否处在左侧边缘 40px 范围内,否则滑动列表也会触发返回touch-action: pan-y(CSS),不然横向事件会被 iOS 抢走transform: translateX() + transition,不要使用 left 或者 margin,因为重排成本较高这是因为 onBackPress 被触发时,页面尚未开始退出,此刻调用 uni.navigateBack() 会与原生退出逻辑发生冲突,最终导致卡住或闪退。
onBackPress 中返回 true,用来表示“返回已被我拦截”,之后自行控制退出动画,并在定时器结束后调用 uni.navigateBack({delta: 1})
onBackPress 中直接 return false,否则 uni-app 会将其视为“不处理”,继续执行原生逻辑plus.key 监听返回键,需要记得在页面 onUnload 中 removeEventListener,否则会引发内存泄漏popGesture 修改配置后必须重新编译并安装,热更新无法使其生效。