1

我有一个视图控制器想要显示来自 PencilKit的 aPKCanvasView和 a 。PKToolPicker这是代码:

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

在此处输入图像描述

但是,如果我以编程ViewController方式使用新的UIWindow. 然后PKToolPicker不显示。

在此处输入图像描述

所以我假设我的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 在那里,但没有一个工具被绘制到屏幕上。

在此处输入图像描述 在此处输入图像描述

编辑 2

我在 中添加了一个计时器ViewController,我注意到当PKToolPicker实际显示时,PKCanvasView实际上成为第一响应者。不是立即,而是几秒钟后。当我使用以编程方式创建的UIWindow时,PKCanvasView永远不会成为第一响应者。所以也许这与我的窗口没有要求以某种方式成为第一响应者这一事实有关。

编辑 3

我设法简化了问题并将其放入您可以在此处查看的示例应用程序中。如果您查看SceneDelegate.swift,那里有创建我自己的窗口的代码。如果我将此代码注释掉,我会毫无问题地看到我的工具选择器。当我取消注释代码时,它不显示工具选择器。

4

1 回答 1

1

我今天只是在玩同样的 API,遇到了同样的问题。我认为问题在于您在场景委托中创建窗口,您缺少: window.makeKeyAndVisible()

加上删除 Info.plist 中的情节提要参考,因为您是在场景委托中手动加载它。UISceneStoryboardFile把里面的钥匙拔掉就行了UIApplicationSceneManifest

我认为问题在于操作系统正在为您创建窗口(基于 Info.plist),但随后您将使用自己手动创建的窗口覆盖该窗口。实际可见的窗口(Info.plist 创建了一个)不能再被引用。

于 2020-04-28T01:03:58.680 回答