簡體   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