所讨论的应用程序必须允许用户选择一种所选显示器的可用屏幕模式。例如,外部显示器本身可能支持 1920x1080,但它的 EDID 也会显示支持的 1920x1200、1280x720 和 1024x768 分辨率。
默认情况下,将外部显示器连接到 iOS 设备似乎总是倾向于外部显示器支持的最高分辨率。我已允许用户从列表中选择UIScreenMode.availableModes
以更改分辨率。一旦选择了模式并将其应用于它,externalScreen.currentMode
它确实会出现正在考虑的新分辨率。
在测试中,我为外部显示器分配了一个全为红色的视图。将分辨率从例如 1920x1080 更改为 1024x768 后,红色框以 4:3 的纵横比显示在显示器上。做同样的事情,但对 1280x720 保持红色框 16:9 填充屏幕与 1080 大致相同。
但是,红色框包含两个带有 AutoLayout 约束的标签。当分辨率改变时,标签的 x/y 坐标相对于红色框保持不变。它们应该在红框中居中,但是当分辨率改变时它们似乎没有重新布局。此外,当分辨率下降时,标签的物理尺寸会变大,这表明它们在某种程度上受到分辨率变化的影响。
那么,红框的子视图(分配给 externalDisplay 的 UIView)如何在更改后更新UIScreenMode.currentMode
?
以下是正在发生的事情的简化版本:
var externalScreen:UIScreen!
var externalWindow: UIWindow!
var extView: MyExternalDisplay?
func initializeExternalScreen(externalScreen:UIScreen) {
self.externalScreen = externalScreen
// Create a new window sized to the external screen's bounds
self.externalWindow = UIWindow(frame: self.externalScreen.bounds)
// Assign screen object to screen property of the new window
self.externalWindow.screen = externalScreen
// Load the clock view
let clockView = self.storyboard?.instantiateViewControllerWithIdentifier("ExternalDisplay") as! ExternalDisplay
clockView.view.frame = self.externalWindow.frame
// Add the view to the window
self.externalWindow.addSubview(clockView.view)
// Create a reference to the clockView
self.extView = clockView
// Make the window visible
self.externalWindow.makeKeyAndVisible()
}
func applyNewMode () {
let newMode = externalScreen.availableModes[1] // 1024x768
externalScreen.currentMode = newMode
}
当收到 screenModeDidChange 通知时调用它。
func handeScreenModeDidChangeNotification (notification:NSNotification) {
extView?.view.frame = externalWindow.frame
extView?.view.layoutSubviews()
}
更新
在通知中添加以下响应screenModeDidChange
似乎 - 有时 - 解决了问题。结果不一致,我不确定这是否是 iOS 9 测试版问题。
func handeScreenModeDidChangeNotification (notification:NSNotification) {
let screen = UIScreen.screens()[1]
initializeExternalScreen(screen)
}
更新#2
虽然使用此处列出的方法似乎可以更改外部屏幕的分辨率,但它不会更改实际的输出分辨率。例如,如果 iOS 设备连接到显示首选 EDID 为 1920x1080 的显示器,则设备将默认使用此分辨率。使用前面提到的方法更改分辨率将更改呈现图像的分辨率,但输出分辨率保持 1920x1080。本质上,所发生的只是显示内容的分辨率降低,而实际输出分辨率保持不变。