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
相关产品推荐
相关产品推荐

