iOS 11及11.2后如何禁止屏幕旋转?iPhone X适配问题
嘿,我之前也帮朋友处理过类似的旧项目适配问题,刚好能给你一套可行的解决方案,分步骤给你讲清楚:
一、先说说系统层面的方案(不适合你的需求)
你提到的在部署设置里关闭旋转,确实是最快的全局禁用方式——在Xcode项目的General标签下,找到Deployment Info,取消勾选不需要的方向就行。但这个方法会作用于所有机型,不符合你「仅针对iPhone X禁止旋转」的需求,所以咱们重点看代码层面的实现。
二、iOS 11.2 之后旧旋转方法失效的替代方案
从iOS 11.2开始,苹果调整了屏幕旋转的回调逻辑,原来的shouldAutorotate、shouldAutorotateToInterfaceOrientation这些方法在很多场景下不再被调用,咱们得用新的方式来控制:
1. 核心思路:机型判断 + 控制器/场景级别的旋转权限控制
因为你的项目是无故事板的旧应用,咱们优先用兼容旧架构的实现,同时精准针对iPhone X系列机型做限制。
2. 具体代码实现
方法一:重写根控制器的旋转权限方法(兼容iOS 11+)
如果你的应用根控制器是自定义的UIViewController(或者导航/标签栏控制器),直接在里面重写以下方法:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations { // 判断是否为iPhone X系列机型(X、XS、XS Max、XR) BOOL isiPhoneXSeries = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone && ([[UIScreen mainScreen] bounds].size.width == 812.0 || [[UIScreen mainScreen] bounds].size.width == 896.0)); if (isiPhoneXSeries) { // 仅允许竖屏 return UIInterfaceOrientationMaskPortrait; } // 其他机型保持原有支持的方向(这里以除了倒置的所有方向为例) return UIInterfaceOrientationMaskAllButUpsideDown; } - (BOOL)shouldAutorotate { BOOL isiPhoneXSeries = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone && ([[UIScreen mainScreen] bounds].size.width == 812.0 || [[UIScreen mainScreen] bounds].size.width == 896.0)); // iPhone X系列强制禁止旋转 return !isiPhoneXSeries; }
划重点:如果你的应用用了
UINavigationController或UITabBarController作为根容器,一定要自定义这些容器类,并重写上面的方法,否则控制器层级的判断会被容器覆盖,导致失效。
方法二:用UIWindowSceneDelegate控制(iOS 13+ 推荐,兼容iOS 11.2+)
如果你的应用已经适配了多场景(Scene),可以在UIWindowSceneDelegate里实现这个更直接的方法:
- (UIInterfaceOrientationMask)windowScene:(UIWindowScene *)windowScene supportedInterfaceOrientationsForWindow:(UIWindow *)window { BOOL isiPhoneXSeries = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone && ([[UIScreen mainScreen] bounds].size.width == 812.0 || [[UIScreen mainScreen] bounds].size.width == 896.0)); return isiPhoneXSeries ? UIInterfaceOrientationMaskPortrait : UIInterfaceOrientationMaskAllButUpsideDown; }
这个方法直接控制对应场景下窗口的旋转权限,不需要考虑控制器层级的传递,逻辑更清晰。
3. 优化机型判断:避免硬编码尺寸(可选)
硬编码屏幕尺寸虽然简单,但如果后续出了新机型可能需要更新。你可以通过读取设备型号来判断,更准确:
#import <sys/utsname.h> // 获取设备型号的工具方法 NSString* getDeviceModel() { struct utsname systemInfo; uname(&systemInfo); return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; } // 在判断中使用 NSString *deviceModel = getDeviceModel(); NSArray *iPhoneXSeriesModels = @[@"iPhone10,3", @"iPhone10,6", @"iPhone11,2", @"iPhone11,4", @"iPhone11,6", @"iPhone11,8"]; BOOL isiPhoneXSeries = [iPhoneXSeriesModels containsObject:deviceModel];
这个列表覆盖了所有iPhone X系列机型,暂时足够你的旧应用使用。
三、验证效果
写完代码后,记得在iPhone X模拟器或真机上测试:
- 尝试旋转设备,确认界面保持竖屏
- 在其他机型(比如iPhone 8)上测试,确保旋转功能正常工作
内容的提问来源于stack exchange,提问作者RickJansen




