【问题标题】:PKToolPicker from PencilKit does not show on programmatically created UIWindowPencilKit 中的 PKToolPicker 不会显示在以编程方式创建的 UIWindow 上
【发布时间】:2020-04-08 17:28:42
【问题描述】:

我有一个视图控制器想要显示来自 PencilKit 的 PKCanvasViewPKToolPicker。代码如下:

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的屏幕截图

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

所以我假设我的ViewController 代码没有任何问题。这可能是我如何创建新 UIWindow 的问题。

我使用来自SceneDelegate.swift 的以下代码(注意我正在使用 iOS 13)创建窗口:

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

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

【问题讨论】:

  • 在我的程序中,调色板在用户使用键盘之前不会出现。一旦出现键盘,调色板就可以随时出现。 (即任何输入字段必须成为第一响应者并在使用 PKToolPicker 之前辞职。)

标签: ios swift ios13 pencilkit


【解决方案1】:

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

加上删除 Info.plist 中的故事板引用,因为您是在场景委托中手动加载它。只需删除 UIApplicationSceneManifest 内的密钥 UISceneStoryboardFile

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

【讨论】:

    猜你喜欢
    • 2015-05-28
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多