【问题标题】:Programmatically dismiss modal dialog in MacOS在 MacOS 中以编程方式关闭模式对话框
【发布时间】:2018-07-19 04:55:35
【问题描述】:

我有一个来自 MacOS 应用程序的 AppDelegate 的警告对话框,需要使用新信息进行更新。当新信息可用时,我想以编程方式关闭旧对话框并呈现新对话框。这两种方法我都试过了,都有问题:

  1. 使用alert.runModal()

    如果我使用上述内容,则会根据需要显示模态。然后我可以稍后使用lockWarningModal.window.close() 关闭对话框,它可以使旧对话框消失,但它会冻结 UI,因此我无法再与之交互。我猜这是因为 @ 987654323@是同步的,主线程还是阻塞的。但是,我不知道如何发布。

  2. 使用alert.beginSheetModal(for: NSApplication.shared.windows.last!) { (response) in }

    如果我使用上述方法并使用NSApplication.shared.windows.last!.endSheet(alert.window) 关闭对话框,那么这可以解决 UI 冻结问题。但是,对话框附加到主应用程序窗口,不会作为模态显示在前面。

如何实现可通过编程方式关闭的模态对话框?

【问题讨论】:

    标签: swift macos nsalert


    【解决方案1】:

    您不能通过简单地关闭其窗口来停止模型事件循环(或警报表)。事实上,使用现代的NSAlert API,您永远不必关闭或订购窗口——框架会为您处理这些。

    对于以runModal() 开头的警报,请使用NSApplicationabortModal()stopModal()stopModal(withCode:)。在runModal() 返回后,向警报窗口发送orderOut(nil) 以将其删除。

    对于之后执行完成块的警报表,请使用NSWindowendSheet(_)endSheet(_:returnCode:)。完成块执行后,警报将自动删除。

    【讨论】:

    • 使用NSApplication.shared.abortModal() 可以在调用lockWarningModal.window.close() 后保持UI 响应。但是,单独调用NSApplication.shared.abortModal() 不会关闭窗口。就您的观点而言,“您永远不必关闭或订购窗口-框架会为您处理”,我是否通过两次调用来实现我的目标做错了什么?
    • 我可能夸大了一点。如果你使用runModal()(这是一个旧的API),你应该使用abortModal()等。人。以编程方式停止模态循环。在处理返回值的代码中(在runModal() 返回之后),向警报窗口发送orderOut(nil)。虽然从技术上讲,您可以“关闭”对话框窗口,但这没有任何意义。这些不是文件,你只是想让它消失。要记住的是:在模型循环结束之前不要订购警报面板。
    • 现代 API 方法(beginSheetModal(for:,completionHandler:) 等)在警报完成时执行完成块。该框架还为您处理订购窗口。
    • 我编辑了答案以阐明何时使用orderOut()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 2021-02-25
    • 2013-08-10
    • 2014-07-22
    • 1970-01-01
    相关资源
    最近更新 更多