如何在macOS Swift应用中关闭窗口时避免同应用其他窗口前置
解决方案
方法一:关闭窗口前让应用主动失去激活状态
通过调用NSApplication.shared.deactivate()让应用放弃活跃状态,这样关闭当前前置窗口后,系统不会自动激活本应用的其他窗口,从而保留原有窗口层级结构。
代码实现
- 为窗口设置代理(可在视图控制器的
viewDidLoad中完成):
override func viewDidLoad() { super.viewDidLoad() view.window?.delegate = self }
- 实现
NSWindowDelegate的windowWillClose(_:)方法:
extension YourViewController: NSWindowDelegate { func windowWillClose(_ notification: Notification) { guard let closingWindow = notification.object as? NSWindow else { return } // 确认应用还有其他可见窗口,避免最后一个窗口关闭时出现异常 let hasOtherVisibleWindows = NSApplication.shared.windows.contains { $0 != closingWindow && $0.isVisible } if hasOtherVisibleWindows { NSApplication.shared.deactivate() } } }
也可直接在关闭窗口的逻辑前调用:
// 先让应用失去激活状态 NSApplication.shared.deactivate() // 关闭目标窗口 view.window?.close()
方法二:激活用户之前使用的外部应用
如果需要精准恢复到用户之前操作的应用(比如Finder),可以先定位并激活该外部应用,再关闭当前窗口,确保本应用窗口不会自动前置。
代码实现
func closeWindowWithoutBringingAppWindowsForward() { let workspace = NSWorkspace.shared let myApp = NSApplication.shared let currentFrontApp = workspace.frontmostApplication // 仅当当前活跃应用是本应用时,才切换到外部应用 if currentFrontApp?.bundleIdentifier == myApp.bundleIdentifier { let otherActiveApps = workspace.runningApplications.filter { $0 != myApp && $0.activationPolicy == .regular && $0.isActive } // 激活第一个找到的外部活跃应用 otherActiveApps.first?.activate(options: .activateIgnoringOtherApps) } // 关闭目标窗口 view.window?.close() }
注意事项
- 方法一的
deactivate()会让应用失去活跃状态,用户需手动点击本应用窗口才能重新激活,完全符合层级保持的需求。 - 方法二更适合需要无缝回到用户之前操作场景的情况,减少操作打断感。
内容的提问来源于stack exchange,提问作者Nighthawk
相关产品推荐
相关产品推荐

