app端监听屏幕旋转唯一可靠方式是uni.onwindowresize,通过windowwidth>screenheight判断横竖屏,需在onunload中调用uni.offwindowresize清理,强制横屏应修改原生配置而非js调用。

App端监听屏幕旋转不能靠 orientationchange
直接监听 window.orientation 或 screen.orientation.type 在 App 端(尤其是 iOS)基本无效:iOS Safari 不暴露该 API,uni-app 编译后的原生 WebView 也不透出标准事件。Android 部分机型即使返回值,也常滞后或错乱——不是设备转了才触发,而是系统重绘后才回调,布局已错位。
真正可用的入口只有一个:uni.onWindowResize。它在 App、H5、小程序三端都稳定触发,且返回的是实时视口尺寸 windowWidth 和 windowHeight,比方向字符串更可靠。
- 不要用
if (res.orientation === 'landscape')判断,iOS 返回undefined,Android 返回值不一致 - 统一用
windowWidth > windowHeight做横竖屏判断,误差极小(仅在极端比例下有误判,UI 层可接受) - 必须在
onUnload中调用uni.offWindowResize清理监听,否则页面复用时会叠加多次回调
uni.setScreenOrientation 在 App 端几乎不生效
文档里写的这个 API,在 iOS 上静默失败,在 Android 上受限极多:要求 targetSdkVersion ≥ 28、Activity 未硬编码 android:screenOrientation、且用户未开启“自动旋转”系统开关。调用后既不报错也不生效,容易误判为代码问题。
如果你的目标是“让某页强制横屏”,正确路径是改原生配置,而不是 JS 调用:
- iOS:在
unpackage/res/ios/Info.plist中添加UISupportedInterfaceOrientations,值必须是数组,只允许UIInterfaceOrientationLandscapeLeft或UIInterfaceOrientationLandscapeRight - Android:在
unpackage/res/android/AndroidManifest.xml对应<activity></activity>加android:screenOrientation="landscape" - uni-app 的
manifest.json中"distribute": { "ios": { "orientation": [...] }, "android": { "orientation": "landscape" } }是编译时注入,必须重新云打包才生效
监听到旋转后,别手动操作 DOM
拿到 windowWidth > windowHeight 为 true 后,常见错误是立刻 document.querySelector('.video-wrap').style.transform = 'rotate(90deg)' —— 这会导致触摸坐标错乱、Canvas 渲染异常、键盘弹出位置偏移,尤其在游戏或相机类页面中直接不可用。
推荐做法是用响应式变量驱动样式切换:
- 在 data 中定义
isLandscape: false - 在
uni.onWindowResize回调里更新它:this.isLandscape = res.size.windowWidth > res.size.windowHeight - 模板中用
<view :class="{ 'landscape-layout': isLandscape }"></view>,配合 CSS 媒体查询或 class 内样式控制宽高、flex-direction 等 - 避免在 JS 里写
style.left、style.top等绝对定位,优先用rpx+@media (orientation: landscape)
真机调试时横屏不生效?先查这三个地方
90% 的“监听没反应”不是代码问题,而是环境配置漏项:
- 没重新云打包:改了
manifest.json或原生配置后,真机调试用“运行到手机”不会生效,必须点“发行 → 原生App-云打包” - iOS Info.plist 缺少
UISupportedInterfaceOrientations~ipad字段(iPad 专用),导致 iPad 横屏失效 - AndroidManifest.xml 中主 Activity 和 SplashActivity 的
screenOrientation设置不一致,系统优先按 SplashActivity 的 orientation 执行,后续页面被强制同步
最稳的验证方式:打包后在手机上长按桌面图标 → “应用信息” → 查看“屏幕方向”是否显示“横屏”或“自动旋转”。如果不是,JS 层再怎么监听也没意义。











