如何仅使用 SwiftUI 从@main App 访问 NSWindow?
Posted
技术标签:
【中文标题】如何仅使用 SwiftUI 从@main App 访问 NSWindow?【英文标题】:How to access NSWindow from @main App using only SwiftUI? 【发布时间】:2020-08-16 02:57:26 【问题描述】:在这个answer,解决方案适用于 Scene plus swiftUI。
但是使用 @main 之类的:
@main
struct MyApp: App
@StateObject private var model = MyModel()
var body: some Scene
WindowGroup
Router
AppContent()
.environmentObject(self.model)
我也尝试通过使用来获取主窗口
var window: NSWindow?
let window = NSApplication.shared.mainWindow
return window
尽管如此,mainWindow
总是返回 nil
更新:
我需要NSWindow
,因为需要符合ASWebAuthenticationPresentationContextProviding
,它必须返回NSWindow
。基本上,我正在尝试做类似的事情:
LoginView(store: AuthStore(window: window))
其中AuthStore
使用AuthenticationServices
执行身份验证。
【问题讨论】:
你没有显示为什么/在哪里需要窗口,你会介绍吗? @Asperi 感谢您的亮点,我更新了问题,如果您现在想看看并提供一些反馈,我将不胜感激 【参考方案1】:基本上,我正在尝试做类似的事情:
LoginView(store: AuthStore(window: window))
这是一个可能的方法的演示(带有一些复制的实体)
class AuthStore
var window: NSWindow
init(window: NSWindow)
self.window = window
struct DemoWindowAccessor: View
@State private var window: NSWindow? // << detected in run-time so optional
var body: some View
VStack
if nil != window
LoginView(store: AuthStore(window: window!)) // << usage
.background(WindowAccessor(window: $window))
struct WindowAccessor: NSViewRepresentable
@Binding var window: NSWindow?
func makeNSView(context: Context) -> NSView
let view = NSView()
DispatchQueue.main.async
self.window = view.window // << right after inserted in window
return view
func updateNSView(_ nsView: NSView, context: Context)
struct LoginView: View
let store: AuthStore
var body: some View
Text("LoginView with Window: \(store.window)")
【讨论】:
谢谢!它就像一个魅力 \o/ 很棒的建议? 在找到您非常有用的示例之前,我问了几乎相同的问题 (***.com/a/65401530/792406),该示例效果非常好,因此感谢您发布。 出于好奇,这种方法是使用新的 SwiftUI 生命周期访问 NSWindow 实例的唯一方法吗?我需要在我的场景中更改窗口的外观和行为。【参考方案2】:方法很多,但有一个陷阱阅读完整答案
NSApplication.shared.keyWindow, NSApp.keyWindow,
NSApp.mainWindow,
有时,这些可能会返回 nil,尤其是在启动期间或应用处于非活动状态时
我认为这是因为从 Appkit 方面设置这些属性可能不是即时的
最好是访问所有窗口
NSApp.windows.first
这将返回所有窗口,但顺序不可预测
如果您有多个窗口,您可以进行进一步过滤以找到所需的窗口,但这种方法避免了其他方法返回 nil 的疯狂行为
【讨论】:
以上是关于如何仅使用 SwiftUI 从@main App 访问 NSWindow?的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:当我按下按钮时如何打开(App-)电话设置?
如何从 SwiftUI 中的 Bundle 中的有效路径或 URL 将图像加载到 Image()?
SwiftUI 中如何获取任意视图触摸位置(全局或局部)的坐标
SwiftUI 中如何获取任意视图触摸位置(全局或局部)的坐标