You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS 11及11.2后如何禁止屏幕旋转?iPhone X适配问题

嘿,我之前也帮朋友处理过类似的旧项目适配问题,刚好能给你一套可行的解决方案,分步骤给你讲清楚:

iOS 11 及以上禁止屏幕旋转的针对性解决方案

一、先说说系统层面的方案(不适合你的需求)

你提到的在部署设置里关闭旋转,确实是最快的全局禁用方式——在Xcode项目的General标签下,找到Deployment Info,取消勾选不需要的方向就行。但这个方法会作用于所有机型,不符合你「仅针对iPhone X禁止旋转」的需求,所以咱们重点看代码层面的实现。

二、iOS 11.2 之后旧旋转方法失效的替代方案

从iOS 11.2开始,苹果调整了屏幕旋转的回调逻辑,原来的shouldAutorotateshouldAutorotateToInterfaceOrientation这些方法在很多场景下不再被调用,咱们得用新的方式来控制:

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;
}

划重点:如果你的应用用了UINavigationControllerUITabBarController作为根容器,一定要自定义这些容器类,并重写上面的方法,否则控制器层级的判断会被容器覆盖,导致失效。

方法二:用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

火山引擎 最新活动