繁体   English   中英

NSOpenPanel、NSSavePanel runModal 通过取消立即取消,但仅在运行 11.4 的 M1 上

[英]NSOpenPanel, NSSavePanel runModal dismisses immediately with cancel, but only on M1 running 11.4

我有一位用户报告打开和保存面板已“自动关闭”。 即打开面板对话框出现然后立即关闭,通过代码采取“取消”路径

文件打开菜单项是 Storyboard 中的标准 firstResponder openDocument IBAction

AppDelegate 中有一个 IBAction openDocument 例程,它发布一个通知,该通知由主 ViewController 观察并创建 NSOpenPanel 并使用 RunModal 显示它

class AppDelegate: NSObject, NSApplicationDelegate {
// standard AppDelegate routines omitted for brevity

   @IBAction func openDocument(_ sender: NSMenuItem) {
         let nc = NotificationCenter.default
         nc.post(Notification(name: Notification.Name("documentOpenRequested"), object: object))        
   }
}

class ViewController: NSViewController {


 override func viewDidLoad() {
       super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(doOpenDocument), name: Notification.Name("documentOpenRequested"), object: nil)
   }

@objc func doOpenDocument(_ notification: Notification) {
        print ("doOpenDocument called on MainThread: \(Thread.current.isMainThread)")
        var URLToOpen: URL?
        if let selectedURL = notification.object as? URL {
           URLToOpen = selectedURL
       } else {
           let openPanel = NSOpenPanel();
           openPanel.allowsMultipleSelection = false;
           openPanel.canChooseDirectories = false;
           openPanel.canCreateDirectories = false;
           openPanel.canChooseFiles = true;
           openPanel.allowedFileTypes = ["sdf", "json", "txt"]
           openPanel.allowsOtherFileTypes = true
           let i = openPanel.runModal();
           if i.rawValue == NSApplication.ModalResponse.OK.rawValue  {
               if let myURL = openPanel.url {
                   URLToOpen = myURL
                   NSDocumentController.shared.noteNewRecentDocumentURL(myURL)
               }
           } else {
                print ("RunModal exited with response not OK")
           }
       }
       guard let theURL = URLToOpen else {
           // URL was bad or user aborted open request, either way just bail
           return
       }
}

预期的行为是 RunModal 显示 OpenDialog 并等待用户访问 select 文件并点击确定或取消,这就是我在我的机器上得到的结果。

但是,在这台用户的机器上(运行 11.4 的 MacBook Pro 13" M1 2020),RunModal 会立即退出,路径会打印“RunModal exited with response not OK”。因此用户无法选择文件

我确实读过一些建议在主队列以外的地方执行 NSOpenPanel 可能会导致崩溃。 Willeke 的参考资料表明,这种情况下的通知将发布在主队列中。 我更新了示例以打印队列是否为主队列,并在我的系统上打印

doOpenDocument 在 MainThread 上调用:true

所以把 NSOpenPanel 放在

       DispatchQueue.main.async {

          let openPanel = ...
       }

似乎无法解决问题。

我无权访问可以复制错误的特定机器,这使得进一步调试变得困难。 “自动取消”行为似乎仅限于这一个用户的机器,但配置很常见,我怀疑我会收到其他报告,即使它仅限于使用 M1 芯片等的特定配置

任何人都可以在这台机器或其他机器上复制这种行为,或者遇到这种“自动取消”发生的任何其他原因吗? (系统设置、病毒检查程序等)?

(更新问题以提供预期的行为和发生的行为、进一步的调试信息、其他人请求的代码信息和建议)

我可以在基于 SwiftUI 的 MacOS X 12.3 实用程序中使用 OS X 12.3.1 和 Xcode 13.3.1 在 M1 iMac 上复制此行为。

该问题尚未得到纠正。 其他开发人员建议我改用 FileDocument 和 DocumentGroup 协议。 没有人可以解释 NSOpenPanel 在 SwiftUI 视图中调用时立即取消的这种异常行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM