NSPopover w pasku menu Mac Catalyst for Mac

Sep 09 2020

Próbuję dodać element MenuBar do mojej aplikacji Mac Catalyst.

Z powodzeniem sprawiłem, że aplikacja na iPada działa na Macu, ale dodanie elementu MenuBar okazuje się dość trudne.

Próbowałem rozwiązać problem za pomocą następujących dwóch linków, ale nie mają one repozytorium GitHub, na które mógłbym spojrzeć, a wyjaśnienia wykonują kilka skoków.

https://www.highcaffeinecontent.com/blog/20190607-Beyond-the-Checkbox-with-Catalyst-and-AppKit https://developer.apple.com/documentation/xcode/creating_a_mac_version_of_your_ipad_app

W tej chwili mam następujący kod w mojej AppDelegate:

#if targetEnvironment(macCatalyst)
    import AppKit
    import Cocoa

#endif
import UIKit
import CoreData

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    #if targetEnvironment(macCatalyst)
        var popover: NSPopover!
        var statusBarItem: NSStatusItem!
    #endif

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        #if targetEnvironment(macCatalyst)
        // Code to include from Mac.
        #endif
        #if targetEnvironment(macCatalyst)
            let contentView = MenuBarView()

            // Create the popover
            let popover = NSPopover()
            popover.contentSize = NSSize(width: 400, height: 500)
            popover.behavior = .transient
            popover.contentViewController = NSHostingController(rootView: contentView)
            self.popover = popover
            
            // Create the status item
            self.statusBarItem = NSStatusBar.system.statusItem(withLength: CGFloat(NSStatusItem.variableLength))
            
            if let button = self.statusBarItem.button {
                button.image = NSImage(named: "MenuBar")
                button.action = #selector(togglePopover(_:))
            }
        #endif
        
        return true
    }
    
    #if targetEnvironment(macCatalyst)
        @objc func togglePopover(_ sender: AnyObject?) {
             if let button = self.statusBarItem.button {
                  if self.popover.isShown {
                       self.popover.performClose(sender)
                  } else {
                       self.popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
                        self.popover.contentViewController?.view.window?.becomeKey()
                  }
             }
        }
    #endif
    
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let windowScene = (scene as? UIWindowScene) else { return }
        
        #if targetEnvironment(macCatalyst)
        if let titlebar = windowScene.titlebar {
            titlebar.titleVisibility = .hidden
            titlebar.toolbar = nil
        }
        #endif

    }

...more code from CoreData

Wyświetlane błędy

Jestem naprawdę nowy w tworzeniu iOS i naprawdę się gubię, więc każda pomoc jest naprawdę doceniana.

Edytować

Tak, zrzut ekranu pochodzi z AppDelegate.

Próbuję zaimplementować coś takiego: https://github.com/AnaghSharma/Ambar-SwiftUI

każda implementacja, którą widziałem do tej pory, umieszczała to w AppDelegate, dlatego też próbuję zrobić to samo.

Odpowiedzi

1 Adam Sep 09 2020 at 22:32

Z twojego zrzutu ekranu wygląda na to, że jest to pakiet AppDelegate dla twojego Maca . W takim przypadku musisz usunąć wszystkie elementy UIKit i #if TARGET_MAC_CATALYAT i zrobić wszystko w AppKit. Oznacza to, że użyj NSResponder zamiast UIResponder itp.

Jeśli chodzi o przykładowy kod, to dobry początek: https://github.com/noahsark769/CatalystPlayground

Zawiera pakiet AppKit i kod do jego załadowania.