You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS16中废弃的shouldAutorotate替代方案及Objective-C示例求助

iOS16 替代 shouldAutorotate 的 Objective-C 适配方案

方案一:利用视图控制器尺寸过渡方法

-viewWillTransitionToSize:withTransitionCoordinator: 是iOS8起就支持的API,iOS16仍可正常使用,会在设备旋转导致视图尺寸变化时触发,适合单视图控制器内的布局更新。

实现代码

#import "YourViewController.h"

@implementation YourViewController

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    
    // iOS13+ 推荐通过窗口场景获取界面方向
    UIWindowScene *scene = self.view.window.windowScene;
    UIInterfaceOrientation currentOrientation = scene.interfaceOrientation;
    
    // 同步更新布局
    [self updateSubviewsLayoutForOrientation:currentOrientation];
    
    // 可选:配合旋转动画同步更新布局
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        [self updateSubviewsLayoutForOrientation:currentOrientation];
    } completion:nil];
}

- (void)updateSubviewsLayoutForOrientation:(UIInterfaceOrientation)orientation {
    if (UIInterfaceOrientationIsPortrait(orientation)) {
        // 竖屏布局调整
        self.titleLabel.frame = CGRectMake(20, 60, self.view.bounds.size.width - 40, 30);
        self.contentView.frame = CGRectMake(0, 100, self.view.bounds.size.width, self.view.bounds.size.height - 100);
    } else {
        // 横屏布局调整
        self.titleLabel.frame = CGRectMake(40, 60, self.view.bounds.size.width - 80, 30);
        self.contentView.frame = CGRectMake(40, 100, self.view.bounds.size.width - 80, self.view.bounds.size.height - 100);
    }
}

@end

方案二:监听窗口场景方向变化通知

如果需要全局监听方向变化,或在非视图控制器类中处理布局,可使用UIWindowSceneDidChangeOrientationNotification通知(iOS13+)。

实现代码

#import "OrientationManager.h"

@implementation OrientationManager

+ (void)setupOrientationObserver {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(onSceneOrientationChanged:)
                                                 name:UIWindowSceneDidChangeOrientationNotification
                                               object:nil];
}

+ (void)onSceneOrientationChanged:(NSNotification *)note {
    UIWindowScene *scene = note.object;
    UIInterfaceOrientation orientation = scene.interfaceOrientation;
    
    // 全局处理布局,或通知目标视图控制器更新
    YourViewController *visibleVC = [self currentVisibleViewController];
    [visibleVC updateSubviewsLayoutForOrientation:orientation];
}

// 辅助方法:获取当前可见的视图控制器
+ (UIViewController *)currentVisibleViewController {
    UIViewController *rootVC = [[UIApplication sharedApplication].delegate window].rootViewController;
    while (rootVC.presentedViewController) {
        rootVC = rootVC.presentedViewController;
        if ([rootVC isKindOfClass:[UINavigationController class]]) {
            rootVC = [(UINavigationController *)rootVC topViewController];
        } else if ([rootVC isKindOfClass:[UITabBarController class]]) {
            rootVC = [(UITabBarController *)rootVC selectedViewController];
        }
    }
    return rootVC;
}

@end

关键注意点

  • 优先选择方案一,它属于视图控制器生命周期方法,能自动绑定视图生命周期,降低内存泄漏风险。
  • 若使用Auto Layout,建议修改约束的constant值而非直接设置frame,更适配Auto Layout体系。
  • iOS13+ 务必通过UIWindowScene的interfaceOrientation获取方向,多场景应用下UIApplication的statusBarOrientation可能不准确。

内容的提问来源于stack exchange,提问作者jsdigital

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 11:55:23