iOS 横竖屏实践(UIKit)

present 场景

关注点

present 页面时,重点是这两个属性:

swift 复制代码
override var supportedInterfaceOrientations: UIInterfaceOrientationMask
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation
  • supportedInterfaceOrientations:页面允许方向
  • preferredInterfaceOrientationForPresentation:模态展示时首选方向

必须满足的规则

preferredInterfaceOrientationForPresentation 必须包含在 supportedInterfaceOrientations 中。

错误示例:

swift 复制代码
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    .landscape
}

override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    .portrait
}

iOS 16 及以下会崩溃:

preferredInterfaceOrientationForPresentation 'portrait' must match a supported interface orientation: 'landscapeLeft, landscapeRight'!

iOS 17 为警告,不崩溃,但仍属于非法配置。

与应用级方向的关系

present 页面还必须与应用级可用方向有交集。

若应用只允许竖屏,而被 present 页面只支持横屏,会出现:

Supported orientations has no common orientation with the application...

推荐写法

swift 复制代码
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    .landscape
}

override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    .landscapeRight
}

如果需要在多个页面混用横竖屏,可在 AppDelegate 放开应用级方向:

swift 复制代码
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    .all
}

push 场景

关注点

push 页面只用看:

swift 复制代码
override var supportedInterfaceOrientations: UIInterfaceOrientationMask

preferredInterfaceOrientationForPresentation 不是 push 的控制项。

与应用级方向的关系

如果应用级只允许竖屏,即使页面声明横屏,也不会崩溃,但横屏不会生效。

iOS 版本行为

iOS 15 及以下

从竖屏页 push 到横屏页,不会自动旋转,需要手动触发:

swift 复制代码
let value: UIInterfaceOrientation = orientation.contains(.landscapeRight) ? .landscapeRight : .portrait
UIDevice.current.setValue(value.rawValue, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()

iOS 16 及以上

会自动旋转。

如需显式请求方向更新,可用 iOS 16 新接口:

swift 复制代码
guard let windowScene = self.view.window?.windowScene else {
    return
}
let preferences = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: orientation)
windowScene.requestGeometryUpdate(preferences) { _ in }
self.setNeedsUpdateOfSupportedInterfaceOrientations()
相关推荐
传奇开心果编程9 小时前
【SwiftUI入门练中学】第7课 动画与手势:让界面更灵动
学习·macos·ui·ios·swiftui·swift
传奇开心果编程1 天前
【SwiftUI娓娓道来】第3课:让界面活起来——交互与动画指南
学习·macos·ui·ios·swiftui·swift
用户38034165882971 天前
控制中心一键后台录音:我被自己的 Spike 骗了两次
ios·swift
东坡肘子2 天前
iPhone Duo 留给开发者的一个月 -- 肘子的 Swift 周报 #155
人工智能·swiftui·swift
茶底世界之下3 天前
导出进度不是一个百分比:AVFoundation 收尾阶段的状态建模
ios·swift
茶底世界之下3 天前
为什么媒体源不能在回调仍执行时提前报告 finish?
swift
茶底世界之下3 天前
为什么视频处理器必须提前声明“它能处理什么帧”
swift
茶底世界之下3 天前
录制结束,不代表视频文件已经交付:AVFoundation 录制完成状态的工程化判断
swift
茶底世界之下9 天前
为什么预览、录制、离线导出不能共享同一个背压策略?
ios·swift
2501_915909069 天前
移动端开发工具链怎么组合比较好,iOS、Android、跨端三套配置方案
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程