【问题标题】:How to Close a window and not bring all other windows of the same app to the front in a macOS app using swift?如何使用swift关闭一个窗口而不将同一应用程序的所有其他窗口置于macOS应用程序的前面?
【发布时间】:2022-10-07 05:14:26
【问题描述】:

我有一个 Mac 应用程序,它有多个具有不同视图的窗口。

在调用view.window?.close()(关闭一个打开的窗口,因为我的 Mac 应用程序有多个打开的窗口)后,我怎样才能阻止所有其他窗口出现在前面?

我希望我的其他窗户保持原位,而不是移动到前面。

请注意,我正在使用 Appkit/Cocoa

  • 一扇窗户应该在前面。您希望哪个窗口或应用程序获得焦点?
  • 我想阻止我的应用程序的其他窗口出现在前面。
  • @Nighthawk:你的意思是你有一个像下面这样的窗口分层(从后到前):你的 3 个应用程序窗口,2 个 Finder 窗口,然后是你的前端应用程序窗口。当你关闭前面的时候,你想防止后面的 3 出来覆盖 2 Finder 窗口?
  • @NSGod 是的,就是这样。

标签: swift macos cocoa appkit


【解决方案1】:

您可以通过继承NSWindow 并在您不想出现的窗口中覆盖canBecomeMaincanBecomeKey 来做到这一点。

一个简单的例子是创建一个基于文档的应用程序,该应用程序允许轻松创建多个窗口,每个文档一个窗口。在 Document nib 文件中,选择文档窗口,打开 Identity 检查器并将自定义类设置为您的自定义 NSWindow 子类(例如 MDWindow)。

我的 Swift 有点生疏,但以下是一个幼稚的实现:

class MDWindow: NSWindow {
var mdShouldBecomeMain : Bool

override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask,
              backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) {
    mdShouldBecomeMain = true
    super.init(contentRect: contentRect, styleMask: style, backing: backingStoreType, defer: flag)
}

override func awakeFromNib() {
    NSLog("\(type(of: self)).\(#function)() \(self.title)")
    NotificationCenter.default.addObserver(self, selector: #selector(mdWindowWillClose),
                        name: NSWindow.willCloseNotification, object: nil)
}

@objc func mdWindowWillClose(_ notification: Notification) {
    NSLog("\(type(of: self)).\(#function)() \(self.title)")
    let window = notification.object as! NSWindow
    if (window != self) {
        mdShouldBecomeMain = false
    }
}

override var canBecomeMain : Bool {
    NSLog("\(type(of: self)).\(#function)() \(self.title)")
    return mdShouldBecomeMain
}

override var canBecomeKey : Bool {
    NSLog("\(type(of: self)).\(#function)() \(self.title)")
    return mdShouldBecomeMain
}
}

awakeFromNib 中设置观察所有窗口的关闭情况。然后,如果您不是要关闭的人,请将标志设置为 false,因为应该成为关键并且应该成为主要。当您关闭一个窗口时,该应用程序会自动检查剩余的窗口以查看它们是否可以成为关键窗口或主窗口。通过覆盖这些值,您可以防止窗口出现。

但是请注意,您最终需要将该标志翻转回 true(可能是在计时器上?),否则即使直接单击窗口也根本不会使它们前进。

【讨论】:

    猜你喜欢
    • 2018-07-17
    • 2011-03-20
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 2019-03-12
    相关资源
    最近更新 更多