PKToolPicker из PencilKit не отображается в программно созданном UIWindow - PullRequest
1 голос
/ 08 апреля 2020

У меня есть контроллер представления, который хочет показать PKCanvasView и PKToolPicker из PencilKit. Вот код:

import UIKit
import PencilKit

class ViewController: UIViewController {
    @IBOutlet weak var canvas: PKCanvasView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        canvas.backgroundColor = .lightGray
        canvas.allowsFingerDrawing = true
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

//      self.showPicker()
        self.perform(#selector(showPicker), with: self, afterDelay: 0)
    }

    @objc private func showPicker() {
        guard let window = UIApplication.shared.windows.filter({ $0.windowScene?.activationState == .foregroundActive }).first else {
            return
        }

        let picker = PKToolPicker.shared(for: window)
        if let picker = picker, picker.isVisible {
            return
        }

        print("Picker not visible")
        picker?.setVisible(true, forFirstResponder: canvas)
        picker?.addObserver(canvas)
        picker?.addObserver(self)

        canvas.becomeFirstResponder()

        self.perform(#selector(showPicker), with: self, afterDelay: 0.5)
    }
}


extension ViewController: PKToolPickerObserver {

}

Моя проблема в том, что когда я программно запускаю ViewController в качестве начального ViewController в раскадровке, PKToolPicker прекрасно себя показывает в нижней части экрана. Вот скриншот рабочего DrawingViewController

enter image description here

Однако, если я программно запускаю ViewController с новым UIWindow. тогда PKToolPicker не показывает.

enter image description here

Итак, я предполагаю, что с моим ViewController кодом все в порядке. Что это может быть проблема с тем, как я создаю новое окно UIWindow.

Я создаю окно со следующим кодом (обратите внимание, я работаю с iOS 13) из SceneDelegate.swift:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
        guard let windowScene = (scene as? UIWindowScene) else { return }

        let window = UIWindow(frame: windowScene.coordinateSpace.bounds)
        window.windowScene = windowScene
        window.rootViewController = UIStoryboard(name: "Main", bundle: .main).instantiateViewController(withIdentifier: "ViewController")

        self.window = window
    }

Я довольно озадачен. PencilKit не дает много предупреждений или ошибок о том, почему он не показывает PKToolPicker. Любой вклад приветствуется.

Редактировать 1

Просто добавив больше информации. Я посмотрел на средство просмотра иерархии, и похоже, что PKToolPicker есть, но ни один из инструментов не отображается на экране.

enter image description here enter image description here

Edit 2

Я добавил таймер в ViewController и заметил, что когда на самом деле отображается PKToolPicker, PKCanvasView фактически становится первым респондентом. Не сразу, а через несколько секунд. Когда я использую программно созданный UIWindow, PKCanvasView никогда не становится первым респондентом. Так что, возможно, это связано с тем, что мое окно каким-то образом не просит быть первым респондентом.

Редактировать 3

Мне удалось упростить проблему и поставить ее в пример приложения, которое вы можете оформить здесь . Если вы посмотрите в SceneDelegate.swift, там есть код для создания моего собственного окна. Если я закомментирую этот код, я вижу свой инструмент без проблем. Когда я раскомментировал код, он не показывает инструмент выбора.

1 Ответ

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

Сегодня я просто играл с этим же API и столкнулся с той же проблемой. Я думаю, что проблема в создании вашего окна в делегате сцены, вам не хватает: window.makeKeyAndVisible()

Это плюс удаление ссылки раскадровки в вашем Info.plist, так как вы вручную загружаете его в делегат сцены. Просто удалите ключ UISceneStoryboardFile внутри UIApplicationSceneManifest

Я думаю, проблема в том, что ОС создает ваше окно для вас (на основе Info.plist), но затем вы переопределяете это окно своим собственным, созданным вручную. один. На фактически видимое окно (созданное Info.plist) больше нельзя ссылаться.

...