必须在 pages.json 中为具体页面 style 配置 softinputmode: "adjustresize",否则安卓端 uni.onkeyboardheightchange 不触发;ios 虽有抖动需过滤 height>50 且延迟更新,监听须 onfocus 注册、onblur 清除。

pages.json 里必须配 softinputMode: "adjustResize"
安卓端不配这句,uni.onKeyboardHeightChange 根本不会触发——不是监听写错了,是原生层压根没把键盘高度事件发上来。iOS 虽然部分机型支持不稳定,但至少能进回调;安卓则是“零响应”。
这个配置必须写在具体页面的 style 下,不能只放在全局 app-plus 里,否则可能影响其他不需要上推的页面(比如地图页、视频页)。
-
"adjustPan"会导致页面整体平移,输入框被顶到屏幕中间甚至顶部,底部按钮消失、光标乱跳 -
"adjustResize"才会让 WebView 视图高度真实收缩,触发布局重排,是“上推”的前提 - 如果页面用了
scroll-view或自定义滚动容器,它可能拦截 resize 行为,导致上推失效
uni.onKeyboardHeightChange 的触发条件和防抖处理
这个 API 只在 App 端生效,H5 和小程序完全不触发。它返回的是真实像素高度(通常 250–300px),但 iOS 上可能出现抖动:比如先报 height: 0,再报 height: 268,甚至反复跳变。
所以不能一收到就直接赋值,得加过滤:
- 只接受
height > 50的值,排除误报 - 用
setTimeout或nextTick延迟应用,避免样式未就绪就更新 -
onBlur里必须调用uni.offKeyboardHeightChange(),否则多次进出页面会叠加监听器,导致keyboardHeight被反复赋值 - 别在
mounted就注册监听,应在onFocus时注册,确保页面已激活
原生 <input> 和 <textarea></textarea> 必须带 adjust-position="true" 和 cursor-spacing
这两个属性是 App 端自动上推的“开关”,但只对原生组件生效。第三方封装组件(如 u-input、uni-data-picker)往往不透传,容易踩坑。
-
adjust-position="true"是必要开关,不写等于没装发动机 -
cursor-spacing建议设为80–120,太小(如20)推不动,太大(如300)会空出大片空白 - iOS 上
adjust-position对position: fixed的父容器效果打折,需配合uni.pageScrollTo补位 - 如果用了 uView 的
<u-input></u-input>,得查文档确认是否支持透传;不行就换回原生<input>
uni.pageScrollTo 滚不到位置?查节点时机和作用域错了
常见错误是直接用 e.detail.scrollTop,那是 scroll-view 自己的偏移,和页面无关。真正要的是输入框相对整个页面顶部的距离。
必须用 uni.createSelectorQuery().in(this) 查当前组件实例内的节点,否则查不到;且务必套 setTimeout(300ms 左右),等键盘开始弹出、视口稳定后再查位置,不然 boundingClientRect() 返回 null。
尤其注意:如果输入框嵌在 scroll-view 里,pageScrollTo 对它无效,得改用 scroll-view 自己的 scrollTop 控制。











