React Native中如何在特定页面临时禁用屏幕旋转?
React Native中如何在特定页面临时禁用屏幕旋转?
嘿,这个需求我之前帮不少开发者解决过,其实分两种方式就能搞定——用第三方库快速实现,或者自己写原生代码定制,我给你详细说下:
方法一:用第三方库快速实现(推荐)
我推荐用@react-native-community/screen-orientation这个库,它已经封装好了跨平台的屏幕方向控制逻辑,不用自己折腾原生代码。
步骤:
- 先安装库:
npm install @react-native-community/screen-orientation --save # 或者用yarn yarn add @react-native-community/screen-orientation
- 在需要锁定旋转的页面组件里,利用生命周期钩子来锁定/解锁方向:
函数组件示例:
import React, { useEffect } from 'react'; import { View, Text } from 'react-native'; import ScreenOrientation from '@react-native-community/screen-orientation'; const LockedRotationScreen = () => { useEffect(() => { // 组件挂载时,锁定为竖屏(你也可以改成其他方向,比如LANDSCAPE) ScreenOrientation.lockAsync(ScreenOrientation.Orientation.PORTRAIT); // 组件卸载时,恢复自动旋转 return () => { ScreenOrientation.unlockAsync(); }; }, []); return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>这个页面不会随设备旋转哦 🎉</Text> </View> ); }; export default LockedRotationScreen;
类组件示例:
import React, { Component } from 'react'; import { View, Text } from 'react-native'; import ScreenOrientation from '@react-native-community/screen-orientation'; class LockedRotationScreen extends Component { componentDidMount() { // 锁定为竖屏 ScreenOrientation.lockAsync(ScreenOrientation.Orientation.PORTRAIT); } componentWillUnmount() { // 恢复自动旋转 ScreenOrientation.unlockAsync(); } render() { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>这个页面不会随设备旋转哦 🎉</Text> </View> ); } } export default LockedRotationScreen;
方法二:自己写原生模块定制(适合高度自定义场景)
如果不想依赖第三方库,也可以自己写原生模块来实现,分iOS和Android两个平台:
iOS端原生实现
- 在你的iOS项目里,新建一个
OrientationManager.m和OrientationManager.h文件:
OrientationManager.h
#import <React/RCTBridgeModule.h> #import <UIKit/UIKit.h> @interface OrientationManager : NSObject <RCTBridgeModule> @end
OrientationManager.m
#import "OrientationManager.h" @implementation OrientationManager RCT_EXPORT_MODULE(); // 锁定为竖屏的方法 RCT_EXPORT_METHOD(lockToPortrait) { dispatch_async(dispatch_get_main_queue(), ^{ if (@available(iOS 16.0, *)) { // iOS 16+ 的新API UIWindowScene *scene = [UIApplication sharedApplication].connectedScenes.allObjects.firstObject; [scene requestGeometryUpdateWithPreferences:[[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskPortrait] errorHandler:^(NSError * _Nonnull error) { NSLog(@"锁定方向失败:%@", error); }]; } else if (@available(iOS 13.0, *)) { // iOS 13-15 的API UIWindowScene *scene = [UIApplication sharedApplication].connectedScenes.allObjects.firstObject; scene.requestedInterfaceOrientationMask = UIInterfaceOrientationMaskPortrait; } else { // iOS 12及以下的API [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES]; } }); } // 解锁旋转的方法 RCT_EXPORT_METHOD(unlockOrientation) { dispatch_async(dispatch_get_main_queue(), ^{ if (@available(iOS 16.0, *)) { UIWindowScene *scene = [UIApplication sharedApplication].connectedScenes.allObjects.firstObject; [scene requestGeometryUpdateWithPreferences:[[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskAll] errorHandler:^(NSError * _Nonnull error) { NSLog(@"解锁方向失败:%@", error); }]; } else if (@available(iOS 13.0, *)) { UIWindowScene *scene = [UIApplication sharedApplication].connectedScenes.allObjects.firstObject; scene.requestedInterfaceOrientationMask = UIInterfaceOrientationMaskAll; } else { [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationUnknown animated:YES]; } }); } @end
- 在JS里调用原生方法:
import { NativeModules } from 'react-native'; const { OrientationManager } = NativeModules; // 在组件挂载时调用锁定 useEffect(() => { OrientationManager.lockToPortrait(); return () => { OrientationManager.unlockOrientation(); }; }, []);
Android端原生实现
- 在你的Android项目里,新建
OrientationManagerModule.java文件(路径:app/src/main/java/com/你的包名/):
package com.你的包名; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import android.content.pm.ActivityInfo; import android.app.Activity; public class OrientationManagerModule extends ReactContextBaseJavaModule { public OrientationManagerModule(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { // 模块名称,JS里会用到 return "OrientationManager"; } // 锁定为竖屏的方法 @ReactMethod public void lockToPortrait() { Activity activity = getCurrentActivity(); if (activity != null) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } // 解锁旋转的方法 @ReactMethod public void unlockOrientation() { Activity activity = getCurrentActivity(); if (activity != null) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } } }
- 注册这个模块,修改
MainApplication.java:
import com.你的包名.OrientationManagerModule; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; // ... @Override protected List<ReactPackage> getPackages() { List<ReactPackage> packages = new PackageList(this).getPackages(); // 添加我们的自定义模块 packages.add(new ReactPackage() { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new OrientationManagerModule(reactContext)); return modules; } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } }); return packages; }
- 在JS里调用的方式和iOS完全一样,直接用
NativeModules.OrientationManager即可。
备注:内容来源于stack exchange,提问作者user27379482
相关产品推荐
相关产品推荐

