ios端键盘遮挡需softinputmode+手动滚动+高度监听协同:pages.json中页面style下设softinputmode:"adjustresize",配合uni.onkeyboardheightchange防抖监听(height>50才生效)、settimeout延时查节点、uni.pagescrollto滚动至输入框绝对位置,并动态控制fixed容器bottom。

iOS端键盘遮挡输入框,不能只靠adjust-position或cursor-spacing——这些属性在微信小程序里有效,在App端(iOS)基本失效;真正起效的是原生层的softinputMode配置 + 手动滚动 + 高度监听三者协同。
pages.json里必须配softinputMode: "adjustResize",但仅对App平台生效
安卓上加了这行,80%遮挡问题当场消失;iOS上它能触发视口压缩,但行为不稳定——部分机型(尤其是iOS 15以下或带缩放键盘的场景)会返回height: 0,或抖动式变化。关键点:
- 必须写在具体页面的
style节点下,不是app-plus全局配置,否则会影响其他页的滚动逻辑 - H5和小程序完全忽略这个字段,写了也白写
- 如果页面用了
scroll-view或自定义position: fixed容器,adjustResize大概率被拦截,此时必须手动补uni.pageScrollTo
监听uni.onKeyboardHeightChange拿真实高度,但iOS要加防抖和阈值
这个API只在App端触发,H5和小程序不走这条路。iOS返回的height经常不准:弹出时可能是0,收起时可能残留20px,甚至连续触发多次不同值。实操要点:
- 用
lodash.debounce或自己写300ms防抖,避免滚动抖动 - 只接受
height > 50的值,过滤掉无效抖动 -
onFocus里注册监听,onBlur里必须调uni.offKeyboardHeightChange(),否则页面反复进入会堆积监听器 - 搭配
cursor-spacing="120"使用,光标离键盘边缘留够安全距离,别设太小(200)
uni.pageScrollTo滚不到位置?因为没等键盘稳定就查节点
常见错误是onFocus立刻调uni.createSelectorQuery().in(this).select(...).boundingClientRect(),结果返回null——键盘还没开始弹,视口尺寸未重算。正确做法:
- 先
setTimeout(() => { ... }, 300),等键盘动画启动、视口稳定后再查 - 查节点必须用
.in(this)绑定当前组件实例,否则跨组件或scroll-view内查不到 - 滚动目标不是
e.detail.scrollTop(那是scroll-view自己的偏移),而是输入框距页面顶部的绝对距离:rect.top + pageScrollTop - 收起键盘后,建议再滚一次
scrollTop: 0或原位置,防止残留偏移
textarea底部固定按钮被顶飞?得用动态bottom + safeAreaInsetBottom: false
当输入框在底部fixed容器里(比如聊天页的发送栏),iOS的adjustResize会把整个页面压扁,但fixed元素仍按原始视口计算位置,结果就是按钮“沉”到键盘底下。解法是放弃依赖系统自动推,改为主动控制:
- 给容器加
:style="{ bottom: keyBoardHeight + 'px' }",高度来自uni.onKeyboardHeightChange - 若用了
u-popup或uni-popup,务必设safeAreaInsetBottom="false",否则iPhone X系列会在底部多留安全区空白,和键盘高度叠加导致错位 - 微信小程序端不支持
uni.onKeyboardHeightChange,得降级:监听window.addEventListener('resize'),对比screen.height与window.innerHeight差值来估算键盘高度(精度差,仅作兜底)
最易被忽略的点:iOS上web-view里的输入框,adjust-position和cursor-spacing全无效,必须靠pages.json配softinputMode + 动态改webview-styles.height,且更新后要加nextTick或setTimeout(, 0)才能触发重排。











