如何在 macOS SwiftUI 应用程序中以编程方式打开“设置/首选项”窗口

问题描述 投票:0回答:5

我创建了一个简单的仅适用于 macOS 的 SwiftUI 应用程序,并按照 Apple 的说明添加了一个设置屏幕

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            RootView()
        }
        Settings {
            SettingsView()
        }
    }
}

它有效:首选项选项显示在应用程序菜单中。现在,我还想以编程方式打开此设置窗口,例如单击按钮时。有没有办法实现这个目标?

我希望

NSApplication
中有一种方法,类似于关于窗口,但似乎没有。

macos swiftui window settings preferences
5个回答
40
投票

通过检查应用程序菜单,我找到了这个解决方案:

NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil)

不过,我认为它可能无法通过使用私有 API 的应用程序审核,因此仍然欢迎不那么阴暗的替代方案。

更新:这实际上已经通过了应用程序审核,所以我将其标记为答案。

更新2:有关 macOS 13 解决方案,请参阅Manny 的回答

更新 3:对于具有 SwiftUI 的 macOS 14,您必须使用

SettingsLink
记录的新视图此处
NSApp.sendAction
不再起作用。


31
投票

在 macOS 13+ 版本上,操作名称 已重命名为 Settings

。
因此,要更新约书亚的答案,这里是使用的解决方案:

NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
我想知道是否有一个设置场景 ID 可以与新的 

openWindow

 环境方法一起使用。 :)


9
投票
在 macOS 13+ 上,我使用此解决方案:

if #available(macOS 13, *) { NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil) } else { NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil) }
    

1
投票
我对已经给出的答案的看法是探测应用程序委托的选择器响应。到目前为止,这对我来说效果很好:

extension NSApplication { func openSettings() { guard let delegate = NSApplication.shared.delegate else { return } // macOS 13 Ventura var selector = Selector(("showSettingsWindow:")); if delegate.responds(to: selector) { delegate.perform(selector, with: nil, with: nil); return; } // macOS 12 Monterrey selector = Selector(("showPreferencesWindow:")); if delegate.responds(to: selector) { delegate.perform(selector, with: nil, with: nil); return; } } }
    

0
投票
这里有一个解决方案

macOS <=12 (Monterey and older), 13 (Ventura) & 14 (Sonoma):

if #available(macOS 14.0, *) { SettingsLink { Text("Settings") } } else { Button(action: { if #available(macOS 13.0, *) { NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil) } else { NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil) } }, label: { Text("Settings") }) }
    
© www.soinside.com 2019 - 2024. All rights reserved.