为什么我无法在 iPad 上填充外部屏幕(但不是在模拟器中)?
Why am I having trouble filling an external screen on iPad (but not in simulator)?
我能够检测到何时检测到屏幕,将其与适当的 windowScene
相关联并向其添加视图。由于this SO question:
class ExternalViewController: UIViewController {
override func viewDidLoad() {
view.backgroundColor = .cyan
print("external frame \(view.frame.width)x\(view.frame.height)")
}
}
class ViewController: UIViewController {
var additionalWindows: [UIWindow] = []
override func viewDidLoad() {
//nb, Apple documentation seems out of date.
//
NotificationCenter.default.addObserver(forName: UIScreen.didConnectNotification, object: nil, queue: nil) { [weak self] notification in
guard let self = self else {return}
guard let newScreen = notification.object as? UIScreen else {return}
// Give the system time to update the connected scenes
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
// Find matching UIWindowScene
let matchingWindowScene = UIApplication.shared.connectedScenes.first {
guard let windowScene = [=11=] as? UIWindowScene else { return false }
return windowScene.screen == newScreen
} as? UIWindowScene
guard let connectedWindowScene = matchingWindowScene else {
NSLog("--- Connected scene was not found ---")
return
//fatalError("Connected scene was not found") // You might want to retry here after some time
}
let screenDimensions = newScreen.bounds
let newWindow = UIWindow(frame: screenDimensions)
NSLog("newWindow \(screenDimensions.width)x\(screenDimensions.height)")
newWindow.windowScene = connectedWindowScene
let vc = ExternalViewController()
vc.mainVC = self
newWindow.rootViewController = vc
newWindow.isHidden = false
self.additionalWindows.append(newWindow)
}
}
}
}
当我在 iOS 模拟器中执行此操作时,我看到我的图形按预期填满了屏幕,但是当 运行 在我的实际设备上时,它的四周都出现了明显的黑色边框.
请注意,这不是默认显示镜像行为中常见的边框 - 16:9 宽高比得以保留,我确实看到了预期的不同图形,(我的示例代码中的纯青色,通常我正在做一些金属渲染,其中有一些超出此处范围的轻微异常,但如果我深入研究它可能会导致一些不同的线索)。
打印消息报告了预期的 1920x1080 尺寸。我对 UIKit 不是很了解,也没有做太多积极的 Apple 开发(我正在清理这里的几个旧项目,希望能够在附近的演出中使用它们来投影视觉效果未来),所以我不知道是否还有其他与我可能遗漏的大小限制等有关的东西,但即使如此,也很难看出为什么它在模拟器中的行为会有所不同。
我从应用商店安装的其他应用确实会在外部显示器上显示全屏图形 - Netflix 显示全屏视频如您所料,概念画板显示的文档表示与您在设备上看到的不同。
因此,在本例中,问题与 Overscan Compensation 有关。感谢 Discord 上的 Jerrot 为我指明了正确的方向。
在我的应用程序上下文中,在连接通知委托中添加 newScreen.overscanCompensation = .none
就足够了(实际上,在那之后延迟几毫秒的部分 - 如果直接应用它不起作用在连接通知中)。在上面链接的问题中,进一步讨论了在不同上下文中可能很重要的其他方面。
这是我的 ViewController
修改以达到预期的结果:
class ViewController: UIViewController {
var additionalWindows: [UIWindow] = []
override func viewDidLoad() {
//nb, Apple documentation seems out of date.
//
NotificationCenter.default.addObserver(forName: UIScreen.didConnectNotification, object: nil, queue: nil) { [weak self] notification in
guard let self = self else {return}
guard let newScreen = notification.object as? UIScreen else {return}
// Give the system time to update the connected scenes
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
// Find matching UIWindowScene
let matchingWindowScene = UIApplication.shared.connectedScenes.first {
guard let windowScene = [=10=] as? UIWindowScene else { return false }
return windowScene.screen == newScreen
} as? UIWindowScene
guard let connectedWindowScene = matchingWindowScene else {
NSLog("--- Connected scene was not found ---")
return
//fatalError("Connected scene was not found") // You might want to retry here after some time
}
let screenDimensions = newScreen.bounds
////// new code here --->
newScreen.overscanCompensation = .none
//////
let newWindow = UIWindow(frame: screenDimensions)
NSLog("newWindow \(screenDimensions.width)x\(screenDimensions.height)")
newWindow.windowScene = connectedWindowScene
let vc = ExternalViewController()
vc.mainVC = self
newWindow.rootViewController = vc
newWindow.isHidden = false
self.additionalWindows.append(newWindow)
}
}
}
}
在这个时代,我觉得默认启用过扫描补偿很奇怪。
我能够检测到何时检测到屏幕,将其与适当的 windowScene
相关联并向其添加视图。由于this SO question:
class ExternalViewController: UIViewController {
override func viewDidLoad() {
view.backgroundColor = .cyan
print("external frame \(view.frame.width)x\(view.frame.height)")
}
}
class ViewController: UIViewController {
var additionalWindows: [UIWindow] = []
override func viewDidLoad() {
//nb, Apple documentation seems out of date.
//
NotificationCenter.default.addObserver(forName: UIScreen.didConnectNotification, object: nil, queue: nil) { [weak self] notification in
guard let self = self else {return}
guard let newScreen = notification.object as? UIScreen else {return}
// Give the system time to update the connected scenes
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
// Find matching UIWindowScene
let matchingWindowScene = UIApplication.shared.connectedScenes.first {
guard let windowScene = [=11=] as? UIWindowScene else { return false }
return windowScene.screen == newScreen
} as? UIWindowScene
guard let connectedWindowScene = matchingWindowScene else {
NSLog("--- Connected scene was not found ---")
return
//fatalError("Connected scene was not found") // You might want to retry here after some time
}
let screenDimensions = newScreen.bounds
let newWindow = UIWindow(frame: screenDimensions)
NSLog("newWindow \(screenDimensions.width)x\(screenDimensions.height)")
newWindow.windowScene = connectedWindowScene
let vc = ExternalViewController()
vc.mainVC = self
newWindow.rootViewController = vc
newWindow.isHidden = false
self.additionalWindows.append(newWindow)
}
}
}
}
当我在 iOS 模拟器中执行此操作时,我看到我的图形按预期填满了屏幕,但是当 运行 在我的实际设备上时,它的四周都出现了明显的黑色边框.
请注意,这不是默认显示镜像行为中常见的边框 - 16:9 宽高比得以保留,我确实看到了预期的不同图形,(我的示例代码中的纯青色,通常我正在做一些金属渲染,其中有一些超出此处范围的轻微异常,但如果我深入研究它可能会导致一些不同的线索)。
打印消息报告了预期的 1920x1080 尺寸。我对 UIKit 不是很了解,也没有做太多积极的 Apple 开发(我正在清理这里的几个旧项目,希望能够在附近的演出中使用它们来投影视觉效果未来),所以我不知道是否还有其他与我可能遗漏的大小限制等有关的东西,但即使如此,也很难看出为什么它在模拟器中的行为会有所不同。
我从应用商店安装的其他应用确实会在外部显示器上显示全屏图形 - Netflix 显示全屏视频如您所料,概念画板显示的文档表示与您在设备上看到的不同。
因此,在本例中,问题与 Overscan Compensation 有关。感谢 Discord 上的 Jerrot 为我指明了正确的方向。
在我的应用程序上下文中,在连接通知委托中添加 newScreen.overscanCompensation = .none
就足够了(实际上,在那之后延迟几毫秒的部分 - 如果直接应用它不起作用在连接通知中)。在上面链接的问题中,进一步讨论了在不同上下文中可能很重要的其他方面。
这是我的 ViewController
修改以达到预期的结果:
class ViewController: UIViewController {
var additionalWindows: [UIWindow] = []
override func viewDidLoad() {
//nb, Apple documentation seems out of date.
//
NotificationCenter.default.addObserver(forName: UIScreen.didConnectNotification, object: nil, queue: nil) { [weak self] notification in
guard let self = self else {return}
guard let newScreen = notification.object as? UIScreen else {return}
// Give the system time to update the connected scenes
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
// Find matching UIWindowScene
let matchingWindowScene = UIApplication.shared.connectedScenes.first {
guard let windowScene = [=10=] as? UIWindowScene else { return false }
return windowScene.screen == newScreen
} as? UIWindowScene
guard let connectedWindowScene = matchingWindowScene else {
NSLog("--- Connected scene was not found ---")
return
//fatalError("Connected scene was not found") // You might want to retry here after some time
}
let screenDimensions = newScreen.bounds
////// new code here --->
newScreen.overscanCompensation = .none
//////
let newWindow = UIWindow(frame: screenDimensions)
NSLog("newWindow \(screenDimensions.width)x\(screenDimensions.height)")
newWindow.windowScene = connectedWindowScene
let vc = ExternalViewController()
vc.mainVC = self
newWindow.rootViewController = vc
newWindow.isHidden = false
self.additionalWindows.append(newWindow)
}
}
}
}
在这个时代,我觉得默认启用过扫描补偿很奇怪。