UIScreen
是 UIKit 提供的一个类,表示设备上的物理屏幕,并提供关于屏幕尺寸和显示属性的信息。它是 iOS 和 tvOS 应用程序中和硬件显示屏直接交互的接口。屏幕是一个关键的系统资源,因为每个 iOS 应用都根据特定设备的屏幕来渲染 UI。
以下是 UIScreen
相关的体系结构和工作方式的详细介绍。
UIScreen 的体系结构 #
1. 主屏幕(Primary Screen) #
在 iOS 和 tvOS 中,设备通常只有一个主屏幕,应用通常使用这个屏幕来显示 UI。
- 主屏幕由类方法
UIScreen.main
表示:let mainScreen = UIScreen.main
UIScreen.main
返回设备的主要显示屏幕的实例,这是绝大多数情况下开发者使用的屏幕。
2. 附加屏幕(External Screens) #
在支持外部显示器的设置中(例如通过 Lightning 或 AirPlay 连接外部显示器),可以通过 UIScreen
的 screens
属性来访问所有活动的屏幕。
- 使用
UIScreen.screens
获取所有屏幕实例:let allScreens = UIScreen.screens print("Number of screens: \(allScreens.count)")
外接屏幕的常用开发场景:
- 演示或播放视频时会将内容显示到外接屏幕。
- iPad 或其他设备支持多窗口时,可同时管理多个显示屏。
注意:
- 如果没有外接屏幕连接,
UIScreen.screens.count
的值是1
(即主屏幕)。
3. 屏幕的层次结构(Windows & Coordinate System) #
每个 UIScreen
包含一个或多个窗口(UIWindow
),这些窗口用于管理应用的视图。
- 主屏幕的窗口可以通过
UIScreen.main.windows
属性访问:let windows = UIScreen.main.windows
窗口层次结构:
- 屏幕上可以有多个窗口,每个窗口有自己的 Z 轴层次。
- 屏幕坐标系的原点 (0, 0) 通常位于左上角,所有的图形绘制均基于这个参考点。
4. 屏幕分辨率和缩放 #
屏幕分辨率以点(points
)为单位,而不是像素(pixels)。屏幕缩放系数(scale
)会确定点与物理像素之间的关系。
- 每个
UIScreen
实例都有一个缩放属性UIScreen.scale
:let scale = UIScreen.main.scale print("Screen Scale: \(scale)")
iOS 设备的常见缩放值 #
缩放值 (scale ) | 描述 | 设备示例 |
---|---|---|
1.0 | 非 Retina 显示 | 旧设备如 iPhone 3GS |
2.0 | Retina 显示 | iPhone 8, iPhone SE (Retina) |
3.0 | Retina HD 显示 | iPhone X, iPhone 12, iPhone 15 |
- 点到像素计算方式:
- 如果某个视图的宽是
100 points
,而设备的scale
是2.0
,那么显示的实际像素宽度是100 points × 2 = 200 pixels
。
- 如果某个视图的宽是
5. 尺寸和边界(Bounds, Native Bounds) #
1. 逻辑边界(Bounds,单位是 points) #
- 每个屏幕都有逻辑边界,表示屏幕在点中可用的区域范围。
- 可以通过
UIScreen.bounds
获取:let screenBounds = UIScreen.main.bounds print("Screen Bounds: \(screenBounds)") // 输出 CGRect
bounds
通常以 设备方向(如竖屏、横屏)自动调整。
2. 物理像素边界(Native Bounds) #
UIScreen.nativeBounds
表示物理像素级别的屏幕尺寸。- 与缩放(
scale
)因子密切相关:let nativeBounds = UIScreen.main.nativeBounds print("Native Bounds: \(nativeBounds)") // 输出像素尺寸 CGRect
3. 物理缩放系数(Native Scale) #
UIScreen.nativeScale
表示屏幕的实际像素缩放系数,这通常与UIScreen.scale
相同,但在某些设备(如 iPhone Plus)上可能有所不同。let nativeScale = UIScreen.main.nativeScale print("Native Scale: \(nativeScale)")
6. 屏幕亮度(Brightness) #
UIScreen
提供了对屏幕亮度的控制。
- 获取和设置亮度:
let brightness = UIScreen.main.brightness print("Screen Brightness: \(brightness)") UIScreen.main.brightness = 0.8 // 设置屏幕亮度(0~1.0)
注意: 修改屏幕亮度需要充分考虑用户体验,屏幕亮度的设置应避免突然变化。
7. 屏幕状态(Captured) #
从 iOS 11 开始引入,UIScreen.captured
指示屏幕是否正在被捕获(如通过屏幕共享或录屏工具)。
- 检查捕获状态:
let isCaptured = UIScreen.main.isCaptured print("Is Screen Captured: \(isCaptured)")
- 这种状态可以用来检测是否有隐私泄露的可能(例如防止敏感数据被录屏泄露)。
8. 自定义 Traits(Display Traits on UIScreen) #
屏幕的特性(traits)通过 UITraitCollection
表示,它能描述屏幕的宽度、高度分类等信息。
- 检测 Trait:
let traitCollection = UIScreen.main.traitCollection print("Horizontal Size Class: \(traitCollection.horizontalSizeClass)")
UIScreen 的常见用途 #
获取设备信息: #
屏幕尺寸(逻辑坐标):
let screenSize = UIScreen.main.bounds.size print("Screen Width: \(screenSize.width), Height: \(screenSize.height)")
分辨率(像素):
let pixelWidth = UIScreen.main.nativeBounds.width let pixelHeight = UIScreen.main.nativeBounds.height print("Pixel Width: \(pixelWidth), Height: \(pixelHeight)")
监听屏幕尺寸或特性变化(多任务、小窗口模式): #
NotificationCenter.default.addObserver(
self,
selector: #selector(screenDidChange),
name: UIScreen.didChangeNotification,
object: nil
)
@objc func screenDidChange() {
print("Screen size or scale changed")
}
UIScreen 的关键属性和方法汇总 #
属性/方法 | 说明 |
---|---|
UIScreen.main | 获取主屏幕实例 |
UIScreen.screens | 返回所有可用屏幕的数组 |
UIScreen.bounds | 屏幕边界,以点为单位(逻辑尺寸) |
UIScreen.nativeBounds | 屏幕边界,以像素为单位 |
UIScreen.scale | 显示内容时,点到像素的比例 |
UIScreen.nativeScale | 原生屏幕像素的缩放因子 |
UIScreen.brightness | 获取或设置屏幕亮度(0 到 1.0) |
UIScreen.isCaptured | 是否正在捕获屏幕 |
UIScreen.traitCollection | 屏幕的当前特性信息(如尺寸分类、用户界面风格) |
总结 #
- 主屏幕
UIScreen.main
是核心: 主屏幕提供了逻辑尺寸、缩放因子、分辨率等核心信息。 - 支持多屏幕: 如果有附加屏幕,
UIScreen.screens
可以提供所有屏幕的完整信息。 - 分辨率与缩放:
UIScreen.scale
和UIScreen.nativeScale
是点和像素转换的关键。 - 动态特性: 支持屏幕特性变化检测(如多任务、小窗口模式)。
- 新特性: 捕获状态 (
isCaptured
),帮助提高隐私保护。
通过 UIScreen
,开发者可以灵活适配设备屏幕大小和功能,提供更好的用户体验。