我试图按照本教程创建一个多屏幕应用程序:
https://www.youtube.com/watch?v=UYviLiI2rlY&t=774s
不幸的是,在第25分钟-第26分钟,我收到一个错误,我的外部屏幕保持黑色:
[Assert] Error in UIKit client: -[UIWindow setScreen:] should not be called if the client adopts
UIScene lifecycle. Call -[UIWindow setWindowScene:] instead.
我的代码是:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var textView: UITextView!
var additionalWindows = [UIWindow]()
override func viewDidLoad() {
super.viewDidLoad()
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}
let screenDimensions = newScreen.bounds
let newWindow = UIWindow(frame: screenDimensions)
newWindow.screen = newScreen
guard let vc = self.storyboard?.instantiateViewController(withIdentifier: "PreviewViewController") as? PreviewViewController else {
fatalError("Unable to find PreviewViewController")
}
newWindow.rootViewController = vc
newWindow.isHidden = false
self.additionalWindows.append(newWindow)
}
}
}
我在newWindow.screen = newScreen
:Setter for 'screen' was deprecated in iOS 13.0
中有一个弃用警报,但我找不到任何有用的东西,也找不到关于如何解决这个问题的过于复杂的东西。
请注意,您"应该"根据externalWindow.rootViewController实例化VC
在我的情况下,我使用外部显示器来显示custom UIView()
,所以我使用空的UIViewController()
,然后将我的视图添加到其中。
private func setupExternalScreen(screen: UIScreen, retryUntilSet: Bool = true, retryTimesUntilDiscarded: Int = 0) {
var matchingWindowScene: UIWindowScene? = nil
let scenes = UIApplication.shared.connectedScenes
for item in scenes {
if let windowScene = item as? UIWindowScene {
if (windowScene.screen == screen) {
matchingWindowScene = windowScene
break
}
}
}
if matchingWindowScene == nil {
if true == retryUntilSet {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
if retryTimesUntilDiscarded < 5 {
self.setupExternalScreen(screen:screen, retryUntilSet: false, retryTimesUntilDiscarded += 1)
} else {
let alert = UIAlertController(title: "Not connected", message: "Reconnect the display and try again", preferredStyle: .alert)
let ok = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(ok)
self.present(alert, animated: true, completion: nil)
}
}
}
return
}
externalWindow = UIWindow(frame: screen.bounds)
externalWindow.rootViewController = UIViewController()
airplayView.frame = externalWindow.frame
if !externalWindow.subviews.contains(airplayView) {
externalWindow.rootViewController?.view.addSubview(airplayView)
if let _ = view.window {
view.window?.makeKey()
}
} else {
airplayView.updateValues()
}
externalWindow.windowScene = matchingWindowScene
externalWindowWindow.isHidden = false
}
如果您的应用程序需要iOS<13您可能需要使用if #available(iOS 13.0, *) {}
决定如何设置外部屏幕。
忘了提。。。externalWindow
在ViewController中声明,我使用第二个屏幕进行请求
lazy var externalWindow = UIWindow()
加上这里提供的答案,我能够在模拟器中工作。似乎对于iOS 13+,你必须在UIApplication.shared.connectedScenes
中找到场景。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var textView: UITextView!
var additionalWindows = [UIWindow]()
override func viewDidLoad() {
super.viewDidLoad()
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() + 1) {
// Find matching UIWindowScene
let matchingWindowScene = UIApplication.shared.connectedScenes.first {
guard let windowScene = $0 as? UIWindowScene else { return false }
return windowScene.screen == newScreen
} as? UIWindowScene
guard let connectedWindowScene = matchingWindowScene else {
fatalError("Connected scene was not found") // You might want to retry here after some time
}
let screenDimensions = newScreen.bounds
let newWindow = UIWindow(frame: screenDimensions)
newWindow.windowScene = connectedWindowScene
guard let vc = self.storyboard?.instantiateViewController(withIdentifier: "PreviewViewController") as? PreviewViewController else {
fatalError("Unable to find PreviewViewController")
}
newWindow.rootViewController = vc
newWindow.isHidden = false
self.additionalWindows.append(newWindow)
}
}
}
}
我不确定时间,.now() + 1
似乎在模拟器上工作,但我还没有尝试过真正的硬件,所以你可能想调整一下。