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()
相关推荐
2501_9151063210 小时前
KXApp 的 VS Code 真机调试:按下 Cmd+R 之后发生了什么
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
2601_9555181812 小时前
36. 跨语言:C/C++与Swift&Objective-C混合编程(一)
objective-c·swift·c/c++·混合编程·跨语言
东坡肘子2 天前
谁是 AI-relay App 的真正威胁 -- 肘子的 Swift 周报 #158
人工智能·swiftui·swift
叫Guava不是瓜娃2 天前
我用 Swift 写了个本地语音输入:按住说话,松开就是整理好的文字(开源)
swift
Yannik3 天前
iOS Swift Package Manager(SPM)私有组件完整实操
ios·swift
我就是不信3 天前
Swift 方法派发机制详解
开发语言·ios·swift
用户38034165882975 天前
八个私有 SPM 包撑起六款 App:分支当版本、钻石依赖,和一次谁都没报错的失效
ios·swift
健了个平_246 天前
【iOS】关于传统竖屏 UIKit 项目如何简单适配 iPhone Duo 的第一版
ios·app·swift
2501_915106326 天前
iOS开发之Xcode常用调试技巧总结
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
sakiko_6 天前
使用SPM(Xcode27), 并解决Package.swift不存在问题
swift