iOS13 внешнее зеркалирование экрана, ошибка «setScreen не должна вызываться» - PullRequest
1 голос
/ 28 апреля 2020

Я пытаюсь представить пользовательский контроллер вида на внешнем подключенном экране в iOS 13. Я следовал этому руководству:

http://www.spazstik-software.com/blog/article/how-to-display-custom-content-on-a-external-screen-from-a-ios-device

У меня есть следующий код:

/// A private method used to setup a external screen with a window
/// loaded with a ExternalScreenViewController
///
/// - parameter screen: A UIScreen object to connect the
/// ExternalScreenViewController too
private func setupExternalScreen(screen: UIScreen) {
  guard externalWindow == nil,
    let vc = self.storyboard?.instantiateViewControllerWithIdentifier("ExternalScreen") as? ExternalScreenViewController else {
      return
  }

  externalWindow = UIWindow(frame: screen.bounds)
  externalWindow!.rootViewController = vc
  externalWindow!.screen = screen
  externalWindow!.hidden = false
}

В строке externalWindow!.screen = screen Я получаю сообщение об ошибке в консоли Xcode 11.4.1:

[Assert] Ошибка в клиенте UIKit: - [ UIWindow setScreen:] не должно вызываться, если клиент принимает жизненный цикл UIScene. Вызов - вместо этого [UIWindow setWindowScene:].

Контроллер пользовательского представления не отображается на внешнем дисплее.

Что я должен изменить? Я хочу работать как с iOS 13.x, так и с предыдущими устройствами.

1 Ответ

1 голос
/ 28 апреля 2020

На устройствах iOS 13 вместо установки screen необходимо установить windowScene для объекта externalWindow. Перед этим вы должны выяснить соответствие windowScene из подключенных сцен UIApplication. Пересмотренный метод выглядит следующим образом:

private func setupExternalScreen(screen: UIScreen, shouldRecurse: Bool = true) {
    // For iOS13 find matching UIWindowScene
    var matchingWindowScene: UIWindowScene? = nil
    if #available(iOS 13.0, *) {
        let scenes = UIApplication.shared.connectedScenes
        for aScene in scenes {
            if let windowScene = aScene as? UIWindowScene {
                // Look for UIWindowScene that has matching screen
                if (windowScene.screen == screen) {
                    matchingWindowScene = windowScene
                    break
                }
            }
        }
        if matchingWindowScene == nil {
            // UIWindowScene has not been created by iOS rendered yet
            // Lets recall self after delay of two seconds
            if true == shouldRecurse {
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
                    self.setupExternalScreen(screen:screen, shouldRecurse: false)
                }
            }
            // Dont proceed furthure in iOS13
            return
        }
    }

    guard externalWindow == nil, let vc = self.storyboard?.instantiateViewControllerWithIdentifier("ExternalScreen") as? ExternalScreenViewController else {
      return
    }

    externalWindow = UIWindow(frame: screen.bounds)
    externalWindow!.rootViewController = vc
    if #available(iOS 13.0, *) {
        // Set windowScene here, no need to set screen
        externalWindow!.windowScene = matchingWindowScene
    } else {
        // Set screen the traditional way
        externalWindow!.screen = screen
    }
    externalWindow!.isHidden = false

}

Примечание: мы должны установить isHidden, поскольку hidden устарело.

...