navigationstyle: "custom" 是前提,必须设置才能启用自定义导航栏;否则原生导航栏会遮盖自定义内容、导致渐变失效、滑动闪屏及状态栏裁切等问题。

navigationStyle: "custom" 是前提,不是可选项
不设 navigationStyle: "custom",所有自定义导航栏逻辑都跑不起来。它不是“换皮肤”,而是告诉 UniApp:“原生导航栏我全接管了,你别渲染任何东西”。一旦漏掉,titleNView: false 在 APP 端可能无效,H5 端会残留空白占位,小程序端则可能和胶囊按钮打架。
常见错误现象:
- 写了
background: linear-gradient(...)但渐变没生效——其实是原生导航栏还在,盖住了你的自定义层 - 滑动时导航栏闪一下再动——说明原生栏先渲染、再被 JS 隐藏,时机错乱
- iOS 上顶部内容被状态栏裁切——没处理
env(safe-area-inset-top),或用了position: fixed但没加top: env(safe-area-inset-top)
渐变背景必须用 CSS 渲染,不能靠 native 层
UniApp 的原生导航栏(哪怕设成透明)不支持 CSS 渐变。要实现带渐变的导航栏,必须用 <view></view> 自绘,且背景色/渐变只能写在该元素的 style 或 class 中。
关键点:
- 不要尝试给
uni-nav-bar组件加渐变——它只是个封装,底层仍走原生逻辑,不认 CSS 渐变 - 推荐写法:用
<view class="nav-bar"></view>,CSS 中定义background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - APP 端若需半透明效果,
background: rgba(102, 126, 234, 0.8)比纯色更稳妥;渐变 + 透明度组合在部分 Android 机型上渲染异常,建议先灰度验证 - H5 端注意:渐变在老版 Safari(iOS 13 以下)需加
-webkit-linear-gradient前缀,否则白屏
滑动隐藏必须监听 pageScroll,不是 onPullDownRefresh
onPullDownRefresh 只响应下拉刷新动作,和滚动无关。pageScroll 才是监听页面纵向滚动的唯一可靠钩子,且在 navigationStyle: "custom" 下仍有效。
实操要点:
- 在页面
onPageScroll回调里读取e.scrollTop,判断是否超过阈值(如 44px)来决定是否隐藏 - 避免直接操作 DOM 的
display或visibility:会导致重排,卡顿明显;改用transform: translateY(-100%)+transition: transform 0.2s ease-out - 别忘了“反向显示”:用户往上滑时要恢复导航栏,否则一滑到底就再也回不来了
- 小程序端需额外兼容:
pageScroll在 tabbar 页面中默认不触发,得在pages.json里加"enablePullDownRefresh": false并确保页面不是tabBar列表页
APP 端状态栏与虚拟导航键必须手动收起
只隐藏导航栏 ≠ 全屏。APP 端真正的沉浸式体验,需要同时处理状态栏(顶部)和虚拟导航键(底部),而这俩和导航栏无关,得用 plus API 单独调。
容易踩的坑:
-
plus.navigator.setFullscreen(true)必须在onShow生命周期里调用,onLoad或mounted会报plus is not defined - 必须包裹
#ifdef APP-PLUS,否则 H5 和小程序运行时报错 -
plus.navigator.hideSystemNavigation()在 HyperOS、ColorOS 12+ 上基本失效,别强求;可用plus.navigator.setFullscreen(true)配合页面padding-bottom: env(safe-area-inset-bottom)缓解底部遮挡 - 隐藏后,自定义导航栏高度别硬写 44px:用
uni.getSystemInfoSync().statusBarHeight动态计算,否则 iPhone 14 Pro 等机型状态栏更高,会压内容










