显示键盘后离开应用程序时出现快照错误(需要 afterScreenUpdates:YES)

Chr*_*raf 6 iphone uikit ios swift

我目前正在启动一个新的测试项目,用于通过单独的(模式)视图导入客户端证书。该应用程序始终以视图“主视图”(Main View)开始,其中我有一些虚拟元素来测试连接是否有效。一旦用户将文件添加到我的应用程序(例如,在邮件中打开它或在模拟器中拖放),“证书导入”视图就会通过 Segue 显示。当用户点击“输入证书密码”文本字段时,会弹出键盘。返回时,如果输入的密码对于导入的 p12 客户端证书正确,则调用 .resignFirstResponder() 并通过标签调用应用程序。我希望当应用程序关闭或多任务处理被激活时,我的“证书导入”视图(证书导入视图)会被关闭。我通过在CertificateImportViewController 上的应用程序委托的applicationWillResignActive(application:) 方法中调用dismiss(animated:completion:) 来实现这一点。

现在,当我关闭应用程序或仅在“证书导入视图”中显示键盘后才切换到多任务处理时,就会出现问题。

当我在以下状态下关闭/多任务应用程序时,我会在调试器控制台中获得相应的条目:

  1. 当显示键盘并且我处于证书导入视图时: [Snapshotting] Snapshotting a view (0x7fa91506b200, UIKeyboardImpl) that is not in a visible window requires afterScreenUpdates:YES.

  2. 即使当我离开证书导入视图并返回“主视图”时:[Snapshotting] Snapshotting a view (0x7fa91506b200, UIKeyboardImpl) that is not in a visible window requires afterScreenUpdates:YES.

  3. 在证书导入视图中显示键盘后,离开应用程序,再次打开应用程序,然后关闭/多任务应用程序:[Snapshotting] Snapshotting a view (0x7f99e3821600, UIKeyboardImpl) that has not been rendered at least once requires afterScreenUpdates:YES.

我试图找出是什么让操作系统认为它必须拍摄包括键盘的快照,即使主视图从未显示键盘。我还试图找出为什么键盘认为它必须在键盘被关闭后对其进行快照(resignFirstResponder())。我不确定如何调试将我的证书导入视图保留在堆栈上的原因(我认为这可能是一个原因)。

AppDelegate.swift

func applicationWillResignActive(_ application: UIApplication) {

    guard let rv = window?.rootViewController as? UINavigationController else {
        print("No Navigation Controller")
        return
    }

    if let r = rv.presentedViewController as? UINavigationController, let c = r.topViewController as? CertificateImportViewController {
        c.dismiss(animated: true, completion: nil)
    }
}


func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {

    self.fileBlobURL = url

    guard let rv = window?.rootViewController as? UINavigationController else {
        print("No Navigation Controller")
        return false
    }

    guard let myEntryViewController = rv.topViewController, myEntryViewController.title == "MainView" else {
        print("Wrong View Controller")
        return false
    }

    myEntryViewController.performSegue(withIdentifier: "ShowCertificateImport", sender: myEntryViewController)

    return true
}
Run Code Online (Sandbox Code Playgroud)

证书导入视图控制器.swift

class CertificateImportViewController: UIViewController {

    var fileURL: URL?
    var credential: URLCredential?

    @IBOutlet weak var certpwTextField: UITextField!
    @IBOutlet weak var certResult: UILabel!
    @IBOutlet weak var saveButton: UIBarButtonItem!

    override func viewDidLoad() {
        super.viewDidLoad()

        certpwTextField.delegate = self

        let appdelegate = UIApplication.shared.delegate as! AppDelegate
        guard let u = appdelegate.fileBlobURL else {
            print("No file blob path found!")
            return
        }

        self.fileURL = u
    }

    @IBAction func cancel(_ sender: UIBarButtonItem) {
        dismiss(animated: true, completion: nil)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        certpwTextField.resignFirstResponder()
        certpwTextField.delegate = nil

    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*raf 5

经过更多的研究,包括大量的试验和错误,我意识到:

然而,如果将来有人找到解决这个问题的解决方案,出于好奇,我会对它是如何完成的非常感兴趣。