如何在设备竖屏状态下获取横屏模式的size class?
获取不同设备方向对应的Size Class
你可以通过以下两种实用方式获取设备不同方向下的Size Class:
1. 临时变更方向读取Trait Collection
这种方式会临时修改设备的几何方向(仅用于计算,不会改变实际UI显示方向),读取对应方向的traitCollection后再恢复原状态:
import UIKit func getSizeClass(for orientation: UIInterfaceOrientation) -> (horizontal: UIUserInterfaceSizeClass, vertical: UIUserInterfaceSizeClass) { guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return (.unspecified, .unspecified) } // 保存当前方向 let originalOrientation = windowScene.interfaceOrientation // 临时切换到目标方向 windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: orientation.supportedInterfaceOrientations)) { _ in } // 获取对应方向的Size Class let horizontal = windowScene.traitCollection.horizontalSizeClass let vertical = windowScene.traitCollection.verticalSizeClass // 恢复原方向 windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: originalOrientation.supportedInterfaceOrientations)) return (horizontal, vertical) }
调用示例:
// 获取横屏左向的Size Class let landscapeSizeClass = getSizeClass(for: .landscapeLeft) print("横屏水平:\(landscapeSizeClass.horizontal),垂直:\(landscapeSizeClass.vertical)")
2. 基于设备类型和方向手动计算
如果不想临时修改设备方向,可根据设备型号和目标方向直接推断Size Class(仅适用于全屏场景,无法处理iPad分屏/Slide Over):
func calculateSizeClass(for orientation: UIInterfaceOrientation) -> (horizontal: UIUserInterfaceSizeClass, vertical: UIUserInterfaceSizeClass) { let screen = UIScreen.main let isPad = screen.traitCollection.userInterfaceIdiom == .pad let isLandscape = orientation.isLandscape if isPad { // iPad全屏状态下所有方向都是Regular return (.regular, .regular) } else { // iPhone系列按屏幕尺寸区分 switch screen.nativeBounds.size.height { case 1136, 1334, 2436, 2532: return isLandscape ? (.compact, .compact) : (.compact, .regular) case 2208, 2688, 2778, 2556: return isLandscape ? (.regular, .compact) : (.compact, .regular) default: return (.unspecified, .unspecified) } } }
实时监听方向变化的Size Class
如果需要在方向切换时实时获取更新后的Size Class,可在ViewController中重写以下方法:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) coordinator.animate(alongsideTransition: { _ in let newHorizontal = self.traitCollection.horizontalSizeClass let newVertical = self.traitCollection.verticalSizeClass // 处理新的Size Class逻辑 }) }
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

