一、媒介
应用RN技术栈实现APP上线后,业务部分向导会上反馈未实现ipad横屏全屏展示,用户体验较差。由此,一场pad横屏全屏展示的APP调优工作由此开展。
实操环境:
- Xcode: 14.2
- react-native-cli: 2.0.1
- react-native: 0.60.3
- iOS: 16.1.2 (iPhone X)
二、实现思路
时间紧使命重,技术实现上,考虑到存量功能代码改造工作量,RN层面临于横屏改造工作量较大,故RN层面整体实现横屏展示时间上不允许,RN侧改造方案放弃。
由于业务方只关注APP某一功能模块,故将改造范围缩减,当业务方点击APP功能模块入口时,允许APP解除屏幕方向锁定,让屏幕方向根据设备的物理方向自动调整。当应用退出当前关注功能模块时,APP屏幕方向锁定,不允许屏幕方向根据设备的物理方向自动调整。
APP默认仅支持竖屏。
2.1 Android端
操作如下:
app/src/main/AndroidManifest.xml配置文件中添加android:screenOrientation="portrait"。
值得留意的是:必要在activity中添加而且是在属性为android:name=".MainActivity"下添加以上配置,如图:
2.2 iOS端
为实现iPad适配,起首必要将Targeted Device Families更改为iPhone, iPad:
在Xcode项目中把相对应的勾去掉即可。
基于项目为react-native技术栈实现,不涉及原生代码,可借助react-native第三方组件:react-native-orientation实现。
安装步骤:
- npm i --save react-native-orientation
- react-native link react-native-orientation (自动link不成功,建议手动link)
复制代码 进入功能模块时,
- import Orientation from 'react-native-orientation';
- onPress={() => {
- // 解除屏幕方向锁定,让屏幕方向根据设备的物理方向自动调整
- console.log('----------解除屏幕方向锁定,让屏幕方向根据设备的物理方向自动调整---------');
- Orientation.unlockAllOrientations();
- ....
- }}
复制代码 退出功能模块时,
- import Orientation from 'react-native-orientation';
- initData = () => {
- // 锁定屏幕竖屏锁定
- console.log('----------锁定屏幕竖屏锁定---------');
- Orientation.lockToPortrait();
- };
复制代码 按照以上实现思路实施后,发现android系统下的pad表现较好,能够按照预期设想自动实现APP横竖屏切换,且内容适配。
但是,iOS系统下的iPhone、iPad表现不尽如人意,固然可以实现屏幕横竖屏自动切换,但是当APP处于横屏状态下时,页面展示结果存在未完全铺睁开的适配题目。
显而易见,iOS系统中当旋转物理设备至横屏时,仍然沿用的设备竖屏状态下的宽高举行页面绘制。关键题目就出在这里。
且发现在RN页面及webview中均存在横屏状态下沿用竖屏状态宽高题目。
按照网上给出的办理方案:
对于iOS,在ios/Info.plist文件中包括以下行就可以了:
- <key>UISupportedInterfaceOrientations</key>
- <array>
- <string>UIInterfaceOrientationPortrait</string>
- </array>
- <key>UISupportedInterfaceOrientations~ipad</key>
- <array>
- <string>UIInterfaceOrientationLandscapeRight</string>
- <string>UIInterfaceOrientationLandscapeLeft</string>
- <string>UIInterfaceOrientationPortrait</string>
- <string>UIInterfaceOrientationPortraitUpsideDown</string>
- </array>
复制代码 经实践发现题目仍旧存在。且存在整个APP应用横竖屏切换时,样式错乱(竖屏状态应用横屏样式,遮挡)题目。
经过控制台日志分析发现如下兼容性提示信息:
- > [Orientation] BUG IN CLIENT OF UIKIT: Setting UIDevice.orientation is not supported. Please use UIWindowScene.requestGeometryUpdate(_:)
复制代码 在 iOS 16 中,通过设置 UIDevice.orientation 来强制旋转屏幕的方向已不再被支持。
根据错误提示,必要使用 UIWindowScene.requestGeometryUpdate(_ 方法来实现。
转为 iOS 15.2.1测试机后,发现以上兼容性提示信息在控制台不再展示。
但是竖屏转横屏后,仍旧存在样式错乱(竖屏状态应用横屏样式,遮挡)题目。
经过项目实践,发现组件react-native-orientation对于iOS系统横竖屏转换支持并不友好,也有可能本身遗漏了xcode配置。
三、延伸阅读
3.1 iOS 原生实现横竖屏切换
3.1.1 iOS16 之前实现横竖屏切换
在 AppDelegate.h 文件中添加一个变量来记载是否必要举行横竖屏切换。
- @property (nonatomic, assign, getter=isLaunchScreen) BOOL launchScreen; /**< 是否是横屏 */
复制代码 在 AppDelegate.m 文件中重写 launchScreen 的 setter 方法:
- - (void)setLaunchScreen:(BOOL)launchScreen {
- _launchScreen = launchScreen;
- [self application:[UIApplication sharedApplication] supportedInterfaceOrientationsForWindow:nil];
- }
复制代码 而且实现 UIApplicationDelegate 的 application:supportedInterfaceOrientationsForWindow: 方法
- - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
- if (self.isLaunchScreen) {
- // 只支持横屏,并且 Home 按键在右边
- return UIInterfaceOrientationMaskLandscapeRight;
- }
- // 只支持竖屏
- return UIInterfaceOrientationMaskPortrait;
- }
复制代码 接下来在必要切换横竖屏的 View 中增加以下方法,就能在 iOS16 之前实现该功能。
- /// 切换设备方向
- /// - Parameter isLaunchScreen: 是否是全屏
- - (void)p_switchOrientationWithLaunchScreen:(BOOL)isLaunchScreen {
- AppDelegate *appdelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
- if (isLaunchScreen) {
- // 全屏操作
- appdelegate.launchScreen = YES;
- } else {
- // 退出全屏操作
- appdelegate.launchScreen = NO;
- }
- // 设置设备的方向
- [self p_swichToNewOrientation:isLaunchScreen ? UIInterfaceOrientationLandscapeRight : UIInterfaceOrientationPortrait];
- }
- /// iOS16 之前进行横竖屏切换方式
- /// - Parameter interfaceOrientation: 需要切换的方向
- - (void)p_swichToNewOrientation:(UIInterfaceOrientation)interfaceOrientation {
- NSNumber *orientationTarget = [NSNumber numberWithInteger:interfaceOrientation];
- [[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
- }
复制代码 经过以上代码,就能实现在 iOS16 之前的设备上举行横竖屏切换,下面开始适配 iOS16 的横竖屏切换。
3.1.2 iOS16 之后实现横竖屏切换
跟 iOS16 之前方式一样,必要设置 launchScreen 标志变量,重写 launchScreen 的 setter 方法,实现 UIApplicationDelegate 的 application:supportedInterfaceOrientationsForWindow: 方法。
在Xcode 14下,必要实现横竖屏切换的 View p_switchOrientationWithLaunchScreen: 方法中增加 iOS16 适配。
- /// 切换设备方向
- /// - Parameter isLaunchScreen: 是否是全屏
- - (void)p_switchOrientationWithLaunchScreen:(BOOL)isLaunchScreen {
- AppDelegate *appdelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
- if (isLaunchScreen) {
- // 全屏操作
- appdelegate.launchScreen = YES;
- } else {
- // 退出全屏操作
- appdelegate.launchScreen = NO;
- }
- if (@available(iOS 16.0, *)) {
- // setNeedsUpdateOfSupportedInterfaceOrientations 方法是 UIViewController 的方法,所以这个操作最好是放在控制器中去操作
- [self setNeedsUpdateOfSupportedInterfaceOrientations];
- NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
- UIWindowScene *scene = [array firstObject];
- // 屏幕方向
- UIInterfaceOrientationMask orientation = isLaunchScreen ? UIInterfaceOrientationMaskLandscapeRight : UIInterfaceOrientationMaskPortrait;
- UIWindowSceneGeometryPreferencesIOS *geometryPreferencesIOS = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:orientation];
- // 开始切换
- [scene requestGeometryUpdateWithPreferences:geometryPreferencesIOS errorHandler:^(NSError * _Nonnull error) {
- NSLog(@"强制%@错误:%@", isLaunchScreen ? @"横屏" : @"竖屏", error);
- }];
- } else {
- [self p_swichToNewOrientation:isLaunchScreen ? UIInterfaceOrientationLandscapeRight : UIInterfaceOrientationPortrait];
- }
- }
复制代码 3.2 react-native-orientation 可用函数
react-native-orientation 组件可用函数如下:
- lockToPortrait()
- lockToLandscape()
- lockToLandscapeLeft()
- lockToLandscapeRight()
- unlockAllOrientations()
- getOrientation(function(err, orientation) 返回的结果有 LANDSCAPE、 PORTRAIT、 UNKNOWN 、PORTRAITUPSIDEDOWN ;
- getSpecificOrientation(function(err, specificOrientation) 返回的结果有 LANDSCAPE-LEFT 、LANDSCAPE-RIGHT、 PORTRAIT 、UNKNOWN 、PORTRAITUPSIDEDOWN;
官方文档中,还有一些变乱的先容,具体可以到官方文档上了解学习。
3.3 从模拟器中删除从前的应用步伐
- 删除...../Library/Developer/Xcode/DerivedData中的所有文件;
- 然后从Xcode(Product->Clean Build Folder)中清除构建文件夹。
然后运行应用步伐,
3.4 Xcode Crash报错提示Message from debugger: Terminated due to signal 9
缘故原由:
当内存大概CPU使用过高时,系统会杀死历程。必要启动使命管理器,杀掉无用历程。
3.5 react-native-full-screen (仅支持Android)
react-native-full-screen 是一个用于 React Native 库,它提供了一种简单的方式来实现Android全屏表现。通过使用这个库,可以轻松地将React Native应用步伐设置为全屏模式,以提供更好的用户体验。
该库提供了一些方法和组件,可以实现全屏表现。此中包括:
- FullScreen.enableFullScreen(): 这个方法可以将应用步伐设置为全屏模式。调用这个方法后,应用步伐将占据整个屏幕,并隐藏系统的状态栏和导航栏。
- FullScreen.disableFullScreen(): 这个方法可以将应用步伐从全屏模式切换回正常模式。调用这个方法后,应用步伐将规复到原来的表现状态,表现系统的状态栏和导航栏。
- FullScreen.FullScreenView: 这个组件可以用作容器,将其包裹在必要全屏表现的内容周围。当这个组件被渲染时,它会自动将其子组件设置为全屏模式。
使用react-native-full-screen库,可以轻松地实现全屏表现,并根据必要在全屏和正常模式之间举行切换。
应用时,起首安装依赖包:
- npm install react-native-full-screen --save
复制代码 然后,链接库。
- react-native link react-native-full-screen
复制代码 使用时,起首导入依赖,
- import FullScreen from 'react-native-full-screen';
复制代码 在必要横屏的代码点,做如下逻辑处置惩罚:
- FullScreen.onFullScreen();
复制代码 若自动link不成功,建议手动link,可参照react-native-orientation。
安装时,留意RN 0.60 及以上不必要实验 link 操作。
(RN 0.60 and and above)
- npm install @hortau/react-native-orientation-locker
复制代码 (RN 0.59 and and below)
- npm install @hortau/react-native-orientation-locker
- react-native link @hortau/react-native-orientation-locker
复制代码 3.6 react-native-orientation-locker
react-native-orientation-locker 使用方式与 react-native-orientation 相同。
四、拓展阅读
- 《react-native-orientation 官方文档》
- 《react-native-orientation-locker 官方文档》
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |