根本原因是原生下拉刷新区域与自定义导航栏层叠冲突——uni-app 将下拉控件渲染在最顶层,而未定位隔离的自定义导航栏(view)随之视觉偏移;pages.json 必须全局统一配置 navigationStyle: "custom",并设置 pullToRefresh.offset 等于导航栏高度(如"88px"),同时导航栏需 fixed 定位+图层优化,内容区用 margin-top 避开且启用内部滚动。

下拉刷新时导航栏跟着动,根本原因是原生下拉刷新区域和自定义导航栏发生了层叠冲突——uni-app 把下拉刷新控件渲染在页面最顶层,而你的自定义导航栏(view)又没做定位隔离,导致视觉上“一起被拖下来”。
pages.json 必须配 navigationStyle: "custom"
这是前提。没这句,onPullDownRefresh 不触发,且系统导航栏仍存在,会和你的自定义 DOM 混合渲染,造成不可控偏移。
- 检查 pages.json 对应页面的
style中是否明确写了"navigationStyle": "custom" - 不要只在某个平台条件编译里加,H5/App/小程序三端都得一致启用
- 配完后,原生导航栏消失,所有标题、返回按钮、胶囊按钮都得你用
view+text+button手动实现
下拉刷新区域要“抬高”,避开自定义导航栏
uni-app 的下拉刷新控件默认从视口顶部(y=0)开始下拉。如果你的自定义导航栏高度是 88px(含状态栏),它就会直接盖在导航栏上,拖动时看起来像导航栏被拽下来。
- 在 pages.json 中,给该页面加
pullToRefresh配置而非仅靠enablePullDownRefresh - 关键参数:
"offset": "88px"(数值需等于你导航栏实际高度,单位必须是 px) - 同时设
"style": "circle",避免 default 样式下整个页面内容跟随下拉 - H5 端不支持
pullToRefresh.offset,需改用自定义下拉逻辑(如监听scroll-view的refresher-triggered)
自定义导航栏必须用 position: fixed 且脱离文档流
很多抖动/位移问题,其实是导航栏被当作普通文档流元素参与了重排。它必须锚定在视口,不受任何滚动或刷新影响。
- 导航栏容器加
position: fixed; top: 0; left: 0; right: 0; z-index: 999; - 务必加上
transform: translateZ(0)或will-change: transform,强制 iOS WebKit 合成图层 - 避免用
margin-top或padding-top推开内容区——这会让内容区有“可滚动空间”,反而诱发 body 滚动干扰 - 内容区第一层容器(如
.page-content)应设margin-top: 88px(同导航栏高度),并启用内部滚动(overflow-y: auto)
真机调试时最容易忽略的点
模拟器看不出问题,但 iOS 真机上,哪怕只差 1px 的 offset 或漏掉一个 transform,下拉时导航栏都会轻微跳动或闪烁。
- 用 Safari 开发者工具连真机,打开
Rendering → Paint Flashing,观察下拉瞬间是否有非预期重绘区域覆盖导航栏 - 检查是否在
onPullDownRefresh里调用了this.$forceUpdate()或频繁修改导航栏绑定的数据,这会导致每帧重绘 - 如果用了 uView 或其他 UI 库的导航栏组件,确认它没有在内部动态添加
style或class导致 layout thrashing


















