簡體   English   中英

如何訪問 macOS NSApp popover 屬性

[英]How to access macOS NSApp popover property

我在我的 macOS 應用程序的主生命周期文件中初始化了一個彈出窗口:

class AppDelegate: NSObject, NSApplicationDelegate{

var statusItem: NSStatusItem?
var popOver = NSPopover()
var authentication = Authentication()

func applicationDidFinishLaunching(_ notification: Notification) {
    
    let menuView = MenuView().environmentObject(authentication)
    
    popOver.behavior = .transient
    popOver.animates = true
    popOver.contentViewController = NSViewController()
    popOver.contentViewController?.view = NSHostingView(rootView: menuView)
    
    popOver.contentViewController?.view.window?.makeKey()
    
    statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
    
    
    if let MenuButton = statusItem?.button{
        
        //            MenuButton.image = NSImage(systemSymbolName: "arrow.up.doc", accessibilityDescription: nil)
        MenuButton.image = NSImage(named: NSImage.Name("icon_2"))
        //                        MenuButton.image?.isTemplate = true
        
        
        MenuButton.action = #selector(MenuButtonToggle)
        
    }
    
    if let window = NSApplication.shared.windows.first {
        window.close()
    }
}

@objc func MenuButtonToggle(sender: AnyObject? = nil){
    
    @Environment(\.openURL) var openURL
    
    if popOver.isShown{
        popOver.performClose(sender)
    }
    else{
        if let menuButton = statusItem?.button{
            NSApplication.shared.activate(ignoringOtherApps: true)
            self.popOver.show(relativeTo: menuButton.bounds, of: menuButton, preferredEdge: NSRectEdge.minY)
        }
    }
}

@objc func closePopover(_ sender: AnyObject? = nil) {
    popOver.performClose(sender)
}

@objc func togglePopover(_ sender: AnyObject? = nil) {
    if popOver.isShown {
        closePopover(sender)
    } else {
        MenuButtonToggle(sender: sender)
    }
}
}

我只是想知道如何在我的 AppDelegate 之外訪問popOver屬性,更具體地說是在我的 SwiftUI 代碼的 rest 中。 我需要能夠在發生某些事情后關閉popOver ,例如:

checkFile(localURL: url, completion: { res, error in
    // Close popover
    // I assume it'll be something like NSApplication.shared.....
})

我的完整應用程序生命周期如下:

import SwiftUI
import Firebase
import Preferences
import Purchases

@main
struct ExampleApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var delegate


var body: some Scene {
    WindowGroup {
        MenuView()
            .environmentObject(self.delegate.authentication)
    }
    WindowGroup("Login") {
        LoginView()
            .environmentObject(self.delegate.authentication)
    }.handlesExternalEvents(matching: Set(arrayLiteral: "LoginView"))
    Settings{
        SettingsView()
            .environmentObject(self.delegate.authentication)
    }
    WindowGroup("Settings") {
        SettingsView()
            .environmentObject(self.delegate.authentication)
    }.handlesExternalEvents(matching: Set(arrayLiteral: "SettingsView"))
}
}

class AppDelegate: NSObject, NSApplicationDelegate{

var statusItem: NSStatusItem?
var popOver = NSPopover()
var authentication = Authentication()

func applicationDidFinishLaunching(_ notification: Notification) {
    
    let menuView = MenuView().environmentObject(authentication)
    
    popOver.behavior = .transient
    popOver.animates = true
    popOver.contentViewController = NSViewController()
    popOver.contentViewController?.view = NSHostingView(rootView: menuView)
    
    popOver.contentViewController?.view.window?.makeKey()
    
    statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
    
    
    if let MenuButton = statusItem?.button{
        
        //            MenuButton.image = NSImage(systemSymbolName: "arrow.up.doc", accessibilityDescription: nil)
        MenuButton.image = NSImage(named: NSImage.Name("icon_2"))
        //                        MenuButton.image?.isTemplate = true
        
        
        MenuButton.action = #selector(MenuButtonToggle)
        
    }
    
    if let window = NSApplication.shared.windows.first {
        window.close()
    }
}

@objc func MenuButtonToggle(sender: AnyObject? = nil){
    
    @Environment(\.openURL) var openURL
    
    if popOver.isShown{
        popOver.performClose(sender)
    }
    else{
        if let menuButton = statusItem?.button{
            NSApplication.shared.activate(ignoringOtherApps: true)
            self.popOver.show(relativeTo: menuButton.bounds, of: menuButton, preferredEdge: NSRectEdge.minY)
        }
    }
}

@objc func closePopover(_ sender: AnyObject? = nil) {
    popOver.performClose(sender)
}

@objc func togglePopover(_ sender: AnyObject? = nil) {
    if popOver.isShown {
        closePopover(sender)
    } else {
        MenuButtonToggle(sender: sender)
    }
}
}

您可以使用NSApplication.sharedNSApp訪問應用程序實例(兩者都引用應用程序實例,並且都記錄在 NSApplication 的頁面上)。 一旦你有了它,你就可以獲得委托,例如:

let delegate = NSApp.delegate as! AppDelegate

(強制轉換委托似乎是安全的,因為您大概知道 a) 應用程序委托存在,以及 b) 它的類型是什么。)

擁有委托后,只需使用它來獲取彈出窗口:

let popover = delegate.popover

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM