Swift中如何为特定ViewController单独锁定屏幕方向?
问题原因
你的配置不生效的核心原因是,当视图控制器嵌套在UINavigationController、UITabBarController这类容器控制器中时,iOS系统会优先使用容器控制器的方向配置,而非子视图控制器的自定义配置,你单独在VC1中添加的属性没有被系统读取到。
解决方案步骤
- 第一步:自定义容器控制器,将方向配置权限下发给当前展示的子视图控制器
分别自定义导航控制器和标签栏控制器子类,代码如下:
// 自定义导航控制器 class CustomNavigationController: UINavigationController { override var shouldAutorotate: Bool { topViewController?.shouldAutorotate ?? false } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { topViewController?.supportedInterfaceOrientations ?? .portrait } } // 自定义标签栏控制器 class CustomTabBarController: UITabBarController { override var shouldAutorotate: Bool { selectedViewController?.shouldAutorotate ?? false } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { selectedViewController?.supportedInterfaceOrientations ?? .portrait } }
第二步:替换项目中原有容器类
把项目中所有用到的UINavigationController、UITabBarController替换为上面自定义的类,Storyboard中直接修改对应控件的Class属性即可,代码初始化的场景直接使用自定义类初始化即可。第三步:保持各子视图控制器的方向配置不变
VC1的原有代码不用修改,VC2添加对应的横屏配置代码即可:
// VC1原有配置 override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait } override var shouldAutorotate: Bool { return false } // VC2对应配置 override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return [.landscapeLeft, .landscapeRight] } override var shouldAutorotate: Bool { return false }
- 可选补充:跳转时强制切换方向
如果需要在VC1和VC2跳转时立刻切换到对应方向,可在各自的viewWillAppear方法中添加强制切换方向的代码:
// VC1的viewWillAppear中添加,强制切竖屏 if #available(iOS 16.0, *) { let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait)) } else { UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation") } // VC2的viewWillAppear中对应改成横屏枚举值即可
注意事项
- 项目设置中的支持方向保持你当前勾选的竖屏、向左横屏、向右横屏即可,不需要修改
- 如果是present出来的全屏视图控制器,不需要修改容器配置即可直接生效,push到导航栈中的视图控制器必须按上述步骤修改容器配置
内容的提问来源于stack exchange,提问作者Yuuu
相关产品推荐
相关产品推荐

